@wordpress/block-editor
Version:
243 lines (204 loc) • 8.67 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.BlockSwitcherDropdownMenu = exports.BlockSwitcher = void 0;
var _element = require("@wordpress/element");
var _i18n = require("@wordpress/i18n");
var _components = require("@wordpress/components");
var _blocks = require("@wordpress/blocks");
var _data = require("@wordpress/data");
var _icons = require("@wordpress/icons");
var _store = require("../../store");
var _useBlockDisplayInformation = _interopRequireDefault(require("../use-block-display-information"));
var _blockIcon = _interopRequireDefault(require("../block-icon"));
var _blockTransformationsMenu = _interopRequireDefault(require("./block-transformations-menu"));
var _blockVariationTransformations = require("./block-variation-transformations");
var _blockStylesMenu = _interopRequireDefault(require("./block-styles-menu"));
var _patternTransformationsMenu = _interopRequireDefault(require("./pattern-transformations-menu"));
var _useBlockDisplayTitle = _interopRequireDefault(require("../block-title/use-block-display-title"));
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const BlockSwitcherDropdownMenu = ({
clientIds,
blocks
}) => {
const {
replaceBlocks,
multiSelect,
updateBlockAttributes
} = (0, _data.useDispatch)(_store.store);
const blockInformation = (0, _useBlockDisplayInformation.default)(blocks[0].clientId);
const {
possibleBlockTransformations,
canRemove,
hasBlockStyles,
icon,
patterns
} = (0, _data.useSelect)(select => {
const {
getBlockRootClientId,
getBlockTransformItems,
__experimentalGetPatternTransformItems,
canRemoveBlocks
} = select(_store.store);
const {
getBlockStyles,
getBlockType
} = select(_blocks.store);
const rootClientId = getBlockRootClientId(Array.isArray(clientIds) ? clientIds[0] : clientIds);
const [{
name: firstBlockName
}] = blocks;
const _isSingleBlockSelected = blocks.length === 1;
const styles = _isSingleBlockSelected && getBlockStyles(firstBlockName);
let _icon;
if (_isSingleBlockSelected) {
_icon = blockInformation?.icon; // Take into account active block variations.
} else {
const isSelectionOfSameType = new Set(blocks.map(({
name
}) => name)).size === 1; // When selection consists of blocks of multiple types, display an
// appropriate icon to communicate the non-uniformity.
_icon = isSelectionOfSameType ? getBlockType(firstBlockName)?.icon : _icons.copy;
}
return {
possibleBlockTransformations: getBlockTransformItems(blocks, rootClientId),
canRemove: canRemoveBlocks(clientIds, rootClientId),
hasBlockStyles: !!styles?.length,
icon: _icon,
patterns: __experimentalGetPatternTransformItems(blocks, rootClientId)
};
}, [clientIds, blocks, blockInformation?.icon]);
const blockVariationTransformations = (0, _blockVariationTransformations.useBlockVariationTransforms)({
clientIds,
blocks
});
const blockTitle = (0, _useBlockDisplayTitle.default)({
clientId: Array.isArray(clientIds) ? clientIds[0] : clientIds,
maximumLength: 35
});
const isReusable = blocks.length === 1 && (0, _blocks.isReusableBlock)(blocks[0]);
const isTemplate = blocks.length === 1 && (0, _blocks.isTemplatePart)(blocks[0]);
function selectForMultipleBlocks(insertedBlocks) {
if (insertedBlocks.length > 1) {
multiSelect(insertedBlocks[0].clientId, insertedBlocks[insertedBlocks.length - 1].clientId);
}
} // Simple block tranformation based on the `Block Transforms` API.
function onBlockTransform(name) {
const newBlocks = (0, _blocks.switchToBlockType)(blocks, name);
replaceBlocks(clientIds, newBlocks);
selectForMultipleBlocks(newBlocks);
}
function onBlockVariationTransform(name) {
updateBlockAttributes(blocks[0].clientId, { ...blockVariationTransformations.find(({
name: variationName
}) => variationName === name).attributes
});
} // Pattern transformation through the `Patterns` API.
function onPatternTransform(transformedBlocks) {
replaceBlocks(clientIds, transformedBlocks);
selectForMultipleBlocks(transformedBlocks);
}
/**
* The `isTemplate` check is a stopgap solution here.
* Ideally, the Transforms API should handle this
* by allowing to exclude blocks from wildcard transformations.
*/
const hasPossibleBlockTransformations = !!possibleBlockTransformations.length && canRemove && !isTemplate;
const hasPossibleBlockVariationTransformations = !!blockVariationTransformations?.length;
const hasPatternTransformation = !!patterns?.length && canRemove;
if (!hasBlockStyles && !hasPossibleBlockTransformations && !hasPossibleBlockVariationTransformations) {
return (0, _element.createElement)(_components.ToolbarGroup, null, (0, _element.createElement)(_components.ToolbarButton, {
disabled: true,
className: "block-editor-block-switcher__no-switcher-icon",
title: blockTitle,
icon: (0, _element.createElement)(_element.Fragment, null, (0, _element.createElement)(_blockIcon.default, {
icon: icon,
showColors: true
}), (isReusable || isTemplate) && (0, _element.createElement)("span", {
className: "block-editor-block-switcher__toggle-text"
}, blockTitle))
}));
}
const blockSwitcherLabel = blockTitle;
const blockSwitcherDescription = 1 === blocks.length ? (0, _i18n.sprintf)(
/* translators: %s: block title. */
(0, _i18n.__)('%s: Change block type or style'), blockTitle) : (0, _i18n.sprintf)(
/* translators: %d: number of blocks. */
(0, _i18n._n)('Change type of %d block', 'Change type of %d blocks', blocks.length), blocks.length);
const hasBlockOrBlockVariationTransforms = hasPossibleBlockTransformations || hasPossibleBlockVariationTransformations;
const showDropDown = hasBlockStyles || hasBlockOrBlockVariationTransforms || hasPatternTransformation;
return (0, _element.createElement)(_components.ToolbarGroup, null, (0, _element.createElement)(_components.ToolbarItem, null, toggleProps => (0, _element.createElement)(_components.DropdownMenu, {
className: "block-editor-block-switcher",
label: blockSwitcherLabel,
popoverProps: {
position: 'bottom right',
variant: 'toolbar',
className: 'block-editor-block-switcher__popover'
},
icon: (0, _element.createElement)(_element.Fragment, null, (0, _element.createElement)(_blockIcon.default, {
icon: icon,
className: "block-editor-block-switcher__toggle",
showColors: true
}), (isReusable || isTemplate) && (0, _element.createElement)("span", {
className: "block-editor-block-switcher__toggle-text"
}, blockTitle)),
toggleProps: {
describedBy: blockSwitcherDescription,
...toggleProps
},
menuProps: {
orientation: 'both'
}
}, ({
onClose
}) => showDropDown && (0, _element.createElement)("div", {
className: "block-editor-block-switcher__container"
}, hasPatternTransformation && (0, _element.createElement)(_patternTransformationsMenu.default, {
blocks: blocks,
patterns: patterns,
onSelect: transformedBlocks => {
onPatternTransform(transformedBlocks);
onClose();
}
}), hasBlockOrBlockVariationTransforms && (0, _element.createElement)(_blockTransformationsMenu.default, {
className: "block-editor-block-switcher__transforms__menugroup",
possibleBlockTransformations: possibleBlockTransformations,
possibleBlockVariationTransformations: blockVariationTransformations,
blocks: blocks,
onSelect: name => {
onBlockTransform(name);
onClose();
},
onSelectVariation: name => {
onBlockVariationTransform(name);
onClose();
}
}), hasBlockStyles && (0, _element.createElement)(_blockStylesMenu.default, {
hoveredBlock: blocks[0],
onSwitch: onClose
})))));
};
exports.BlockSwitcherDropdownMenu = BlockSwitcherDropdownMenu;
const BlockSwitcher = ({
clientIds
}) => {
const blocks = (0, _data.useSelect)(select => select(_store.store).getBlocksByClientId(clientIds), [clientIds]);
if (!blocks.length || blocks.some(block => !block)) {
return null;
}
return (0, _element.createElement)(BlockSwitcherDropdownMenu, {
clientIds: clientIds,
blocks: blocks
});
};
exports.BlockSwitcher = BlockSwitcher;
var _default = BlockSwitcher;
exports.default = _default;
//# sourceMappingURL=index.js.map