@gechiui/block-editor
Version:
207 lines (171 loc) • 7.46 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.useInnerBlocksProps = useInnerBlocksProps;
var _element = require("@gechiui/element");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _classnames = _interopRequireDefault(require("classnames"));
var _compose = require("@gechiui/compose");
var _data = require("@gechiui/data");
var _blocks = require("@gechiui/blocks");
var _buttonBlockAppender = _interopRequireDefault(require("./button-block-appender"));
var _defaultBlockAppender = _interopRequireDefault(require("./default-block-appender"));
var _useNestedSettingsUpdate = _interopRequireDefault(require("./use-nested-settings-update"));
var _useInnerBlockTemplateSync = _interopRequireDefault(require("./use-inner-block-template-sync"));
var _getBlockContext = _interopRequireDefault(require("./get-block-context"));
var _blockList = require("../block-list");
var _blockContext = require("../block-context");
var _context = require("../block-edit/context");
var _useBlockSync = _interopRequireDefault(require("../provider/use-block-sync"));
var _store = require("../../store");
var _useBlockDropZone = _interopRequireDefault(require("../use-block-drop-zone"));
/**
* External dependencies
*/
/**
* GeChiUI dependencies
*/
/**
* Internal dependencies
*/
/**
* InnerBlocks is a component which allows a single block to have multiple blocks
* as children. The UncontrolledInnerBlocks component is used whenever the inner
* blocks are not controlled by another entity. In other words, it is normally
* used for inner blocks in the post editor
*
* @param {Object} props The component props.
*/
function UncontrolledInnerBlocks(props) {
const {
clientId,
allowedBlocks,
__experimentalDefaultBlock,
__experimentalDirectInsert,
template,
templateLock,
wrapperRef,
templateInsertUpdatesSelection,
__experimentalCaptureToolbars: captureToolbars,
__experimentalAppenderTagName,
renderAppender,
orientation,
placeholder,
__experimentalLayout
} = props;
(0, _useNestedSettingsUpdate.default)(clientId, allowedBlocks, __experimentalDefaultBlock, __experimentalDirectInsert, templateLock, captureToolbars, orientation, __experimentalLayout);
(0, _useInnerBlockTemplateSync.default)(clientId, template, templateLock, templateInsertUpdatesSelection);
const context = (0, _data.useSelect)(select => {
const block = select(_store.store).getBlock(clientId);
const blockType = (0, _blocks.getBlockType)(block.name);
if (!blockType || !blockType.providesContext) {
return;
}
return (0, _getBlockContext.default)(block.attributes, blockType);
}, [clientId]); // This component needs to always be synchronous as it's the one changing
// the async mode depending on the block selection.
return (0, _element.createElement)(_blockContext.BlockContextProvider, {
value: context
}, (0, _element.createElement)(_blockList.BlockListItems, {
rootClientId: clientId,
renderAppender: renderAppender,
__experimentalAppenderTagName: __experimentalAppenderTagName,
__experimentalLayout: __experimentalLayout,
wrapperRef: wrapperRef,
placeholder: placeholder
}));
}
/**
* The controlled inner blocks component wraps the uncontrolled inner blocks
* component with the blockSync hook. This keeps the innerBlocks of the block in
* the block-editor store in sync with the blocks of the controlling entity. An
* example of an inner block controller is a template part block, which provides
* its own blocks from the template part entity data source.
*
* @param {Object} props The component props.
*/
function ControlledInnerBlocks(props) {
(0, _useBlockSync.default)(props);
return (0, _element.createElement)(UncontrolledInnerBlocks, props);
}
const ForwardedInnerBlocks = (0, _element.forwardRef)((props, ref) => {
const innerBlocksProps = useInnerBlocksProps({
ref
}, props);
return (0, _element.createElement)("div", {
className: "block-editor-inner-blocks"
}, (0, _element.createElement)("div", innerBlocksProps));
});
/**
* This hook is used to lightly mark an element as an inner blocks wrapper
* element. Call this hook and pass the returned props to the element to mark as
* an inner blocks wrapper, automatically rendering inner blocks as children. If
* you define a ref for the element, it is important to pass the ref to this
* hook, which the hook in turn will pass to the component through the props it
* returns. Optionally, you can also pass any other props through this hook, and
* they will be merged and returned.
*
* @param {Object} props Optional. Props to pass to the element. Must contain
* the ref if one is defined.
* @param {Object} options Optional. Inner blocks options.
*
* @see https://github.com/GeChiUI/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md
*/
function useInnerBlocksProps() {
let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
const {
clientId
} = (0, _context.useBlockEditContext)();
const isSmallScreen = (0, _compose.useViewportMatch)('medium', '<');
const {
__experimentalCaptureToolbars,
hasOverlay
} = (0, _data.useSelect)(select => {
if (!clientId) {
return {};
}
const {
getBlockName,
isBlockSelected,
hasSelectedInnerBlock,
isNavigationMode
} = select(_store.store);
const blockName = getBlockName(clientId);
const enableClickThrough = isNavigationMode() || isSmallScreen;
return {
__experimentalCaptureToolbars: select(_blocks.store).hasBlockSupport(blockName, '__experimentalExposeControlsToChildren', false),
hasOverlay: blockName !== 'core/template' && !isBlockSelected(clientId) && !hasSelectedInnerBlock(clientId, true) && enableClickThrough
};
}, [clientId, isSmallScreen]);
const ref = (0, _compose.useMergeRefs)([props.ref, (0, _useBlockDropZone.default)({
rootClientId: clientId
})]);
const innerBlocksProps = {
__experimentalCaptureToolbars,
...options
};
const InnerBlocks = innerBlocksProps.value && innerBlocksProps.onChange ? ControlledInnerBlocks : UncontrolledInnerBlocks;
return { ...props,
ref,
className: (0, _classnames.default)(props.className, 'block-editor-block-list__layout', {
'has-overlay': hasOverlay
}),
children: clientId ? (0, _element.createElement)(InnerBlocks, (0, _extends2.default)({}, innerBlocksProps, {
clientId: clientId
})) : (0, _element.createElement)(_blockList.BlockListItems, options)
};
}
useInnerBlocksProps.save = _blocks.__unstableGetInnerBlocksProps; // Expose default appender placeholders as components.
ForwardedInnerBlocks.DefaultBlockAppender = _defaultBlockAppender.default;
ForwardedInnerBlocks.ButtonBlockAppender = _buttonBlockAppender.default;
ForwardedInnerBlocks.Content = () => useInnerBlocksProps.save().children;
/**
* @see https://github.com/GeChiUI/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md
*/
var _default = ForwardedInnerBlocks;
exports.default = _default;
//# sourceMappingURL=index.js.map