@gechiui/block-editor
Version:
336 lines (284 loc) • 9.73 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.BlockListBlockContext = void 0;
var _element = require("@gechiui/element");
var _classnames = _interopRequireDefault(require("classnames"));
var _lodash = require("lodash");
var _blocks = require("@gechiui/blocks");
var _components = require("@gechiui/components");
var _data = require("@gechiui/data");
var _compose = require("@gechiui/compose");
var _dom = require("@gechiui/dom");
var _blockEdit = _interopRequireDefault(require("../block-edit"));
var _blockInvalidWarning = _interopRequireDefault(require("./block-invalid-warning"));
var _blockCrashWarning = _interopRequireDefault(require("./block-crash-warning"));
var _blockCrashBoundary = _interopRequireDefault(require("./block-crash-boundary"));
var _blockHtml = _interopRequireDefault(require("./block-html"));
var _useBlockProps = require("./use-block-props");
var _store = require("../../store");
/**
* External dependencies
*/
/**
* GeChiUI dependencies
*/
/**
* Internal dependencies
*/
const BlockListBlockContext = (0, _element.createContext)();
/**
* Merges wrapper props with special handling for classNames and styles.
*
* @param {Object} propsA
* @param {Object} propsB
*
* @return {Object} Merged props.
*/
exports.BlockListBlockContext = BlockListBlockContext;
function mergeWrapperProps(propsA, propsB) {
const newProps = { ...propsA,
...propsB
};
if (propsA && propsB && propsA.className && propsB.className) {
newProps.className = (0, _classnames.default)(propsA.className, propsB.className);
}
if (propsA && propsB && propsA.style && propsB.style) {
newProps.style = { ...propsA.style,
...propsB.style
};
}
return newProps;
}
function Block(_ref) {
let {
children,
isHtml,
...props
} = _ref;
return (0, _element.createElement)("div", (0, _useBlockProps.useBlockProps)(props, {
__unstableIsHtml: isHtml
}), children);
}
function BlockListBlock(_ref2) {
let {
mode,
isLocked,
canRemove,
clientId,
isSelected,
isSelectionEnabled,
className,
name,
isValid,
attributes,
wrapperProps,
setAttributes,
onReplace,
onInsertBlocksAfter,
onMerge,
toggleSelection
} = _ref2;
const {
removeBlock
} = (0, _data.useDispatch)(_store.store);
const onRemove = (0, _element.useCallback)(() => removeBlock(clientId), [clientId]); // We wrap the BlockEdit component in a div that hides it when editing in
// HTML mode. This allows us to render all of the ancillary pieces
// (InspectorControls, etc.) which are inside `BlockEdit` but not
// `BlockHTML`, even in HTML mode.
let blockEdit = (0, _element.createElement)(_blockEdit.default, {
name: name,
isSelected: isSelected,
attributes: attributes,
setAttributes: setAttributes,
insertBlocksAfter: isLocked ? undefined : onInsertBlocksAfter,
onReplace: canRemove ? onReplace : undefined,
onRemove: canRemove ? onRemove : undefined,
mergeBlocks: canRemove ? onMerge : undefined,
clientId: clientId,
isSelectionEnabled: isSelectionEnabled,
toggleSelection: toggleSelection
});
const blockType = (0, _blocks.getBlockType)(name); // Determine whether the block has props to apply to the wrapper.
if (blockType !== null && blockType !== void 0 && blockType.getEditWrapperProps) {
wrapperProps = mergeWrapperProps(wrapperProps, blockType.getEditWrapperProps(attributes));
}
const isAligned = wrapperProps && !!wrapperProps['data-align']; // For aligned blocks, provide a wrapper element so the block can be
// positioned relative to the block column.
if (isAligned) {
blockEdit = (0, _element.createElement)("div", {
className: "gc-block",
"data-align": wrapperProps['data-align']
}, blockEdit);
}
let block;
if (!isValid) {
const saveContent = (0, _blocks.getSaveContent)(blockType, attributes);
block = (0, _element.createElement)(Block, {
className: "has-warning"
}, (0, _element.createElement)(_blockInvalidWarning.default, {
clientId: clientId
}), (0, _element.createElement)(_element.RawHTML, null, (0, _dom.safeHTML)(saveContent)));
} else if (mode === 'html') {
// Render blockEdit so the inspector controls don't disappear.
// See #8969.
block = (0, _element.createElement)(_element.Fragment, null, (0, _element.createElement)("div", {
style: {
display: 'none'
}
}, blockEdit), (0, _element.createElement)(Block, {
isHtml: true
}, (0, _element.createElement)(_blockHtml.default, {
clientId: clientId
})));
} else if ((blockType === null || blockType === void 0 ? void 0 : blockType.apiVersion) > 1) {
block = blockEdit;
} else {
block = (0, _element.createElement)(Block, wrapperProps, blockEdit);
}
const value = {
clientId,
className,
wrapperProps: (0, _lodash.omit)(wrapperProps, ['data-align']),
isAligned
};
const memoizedValue = (0, _element.useMemo)(() => value, Object.values(value));
return (0, _element.createElement)(BlockListBlockContext.Provider, {
value: memoizedValue
}, (0, _element.createElement)(_blockCrashBoundary.default, {
fallback: (0, _element.createElement)(Block, {
className: "has-warning"
}, (0, _element.createElement)(_blockCrashWarning.default, null))
}, block));
}
const applyWithSelect = (0, _data.withSelect)((select, _ref3) => {
let {
clientId,
rootClientId
} = _ref3;
const {
isBlockSelected,
getBlockMode,
isSelectionEnabled,
getTemplateLock,
__unstableGetBlockWithoutInnerBlocks,
canRemoveBlock,
canMoveBlock
} = select(_store.store);
const block = __unstableGetBlockWithoutInnerBlocks(clientId);
const isSelected = isBlockSelected(clientId);
const templateLock = getTemplateLock(rootClientId);
const canRemove = canRemoveBlock(clientId, rootClientId);
const canMove = canMoveBlock(clientId, rootClientId); // The fallback to `{}` is a temporary fix.
// This function should never be called when a block is not present in
// the state. It happens now because the order in withSelect rendering
// is not correct.
const {
name,
attributes,
isValid
} = block || {}; // Do not add new properties here, use `useSelect` instead to avoid
// leaking new props to the public API (editor.BlockListBlock filter).
return {
mode: getBlockMode(clientId),
isSelectionEnabled: isSelectionEnabled(),
isLocked: !!templateLock,
canRemove,
canMove,
// Users of the editor.BlockListBlock filter used to be able to
// access the block prop.
// Ideally these blocks would rely on the clientId prop only.
// This is kept for backward compatibility reasons.
block,
name,
attributes,
isValid,
isSelected
};
});
const applyWithDispatch = (0, _data.withDispatch)((dispatch, ownProps, _ref4) => {
let {
select
} = _ref4;
const {
updateBlockAttributes,
insertBlocks,
mergeBlocks,
replaceBlocks,
toggleSelection,
__unstableMarkLastChangeAsPersistent
} = dispatch(_store.store); // Do not add new properties here, use `useDispatch` instead to avoid
// leaking new props to the public API (editor.BlockListBlock filter).
return {
setAttributes(newAttributes) {
const {
getMultiSelectedBlockClientIds
} = select(_store.store);
const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds();
const {
clientId
} = ownProps;
const clientIds = multiSelectedBlockClientIds.length ? multiSelectedBlockClientIds : [clientId];
updateBlockAttributes(clientIds, newAttributes);
},
onInsertBlocks(blocks, index) {
const {
rootClientId
} = ownProps;
insertBlocks(blocks, index, rootClientId);
},
onInsertBlocksAfter(blocks) {
const {
clientId,
rootClientId
} = ownProps;
const {
getBlockIndex
} = select(_store.store);
const index = getBlockIndex(clientId);
insertBlocks(blocks, index + 1, rootClientId);
},
onMerge(forward) {
const {
clientId
} = ownProps;
const {
getPreviousBlockClientId,
getNextBlockClientId
} = select(_store.store);
if (forward) {
const nextBlockClientId = getNextBlockClientId(clientId);
if (nextBlockClientId) {
mergeBlocks(clientId, nextBlockClientId);
}
} else {
const previousBlockClientId = getPreviousBlockClientId(clientId);
if (previousBlockClientId) {
mergeBlocks(previousBlockClientId, clientId);
}
}
},
onReplace(blocks, indexToSelect, initialPosition) {
if (blocks.length && !(0, _blocks.isUnmodifiedDefaultBlock)(blocks[blocks.length - 1])) {
__unstableMarkLastChangeAsPersistent();
}
replaceBlocks([ownProps.clientId], blocks, indexToSelect, initialPosition);
},
toggleSelection(selectionEnabled) {
toggleSelection(selectionEnabled);
}
};
});
var _default = (0, _compose.compose)(_compose.pure, applyWithSelect, applyWithDispatch, // block is sometimes not mounted at the right time, causing it be undefined
// see issue for more info
// https://github.com/GeChiUI/gutenberg/issues/17013
(0, _compose.ifCondition)(_ref5 => {
let {
block
} = _ref5;
return !!block;
}), (0, _components.withFilters)('editor.BlockListBlock'))(BlockListBlock);
exports.default = _default;
//# sourceMappingURL=block.js.map