@wordpress/block-editor
Version:
280 lines (242 loc) • 10.1 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.BlockSettingsDropdown = BlockSettingsDropdown;
exports.default = void 0;
var _element = require("@wordpress/element");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _blocks = require("@wordpress/blocks");
var _components = require("@wordpress/components");
var _data = require("@wordpress/data");
var _icons = require("@wordpress/icons");
var _i18n = require("@wordpress/i18n");
var _keyboardShortcuts = require("@wordpress/keyboard-shortcuts");
var _compose = require("@wordpress/compose");
var _blockActions = _interopRequireDefault(require("../block-actions"));
var _blockIcon = _interopRequireDefault(require("../block-icon"));
var _blockHtmlConvertButton = _interopRequireDefault(require("./block-html-convert-button"));
var _blockSettingsMenuFirstItem = _interopRequireDefault(require("./block-settings-menu-first-item"));
var _blockSettingsMenuControls = _interopRequireDefault(require("../block-settings-menu-controls"));
var _store = require("../../store");
var _utils = require("../block-toolbar/utils");
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const POPOVER_PROPS = {
className: 'block-editor-block-settings-menu__popover',
position: 'bottom right',
variant: 'toolbar'
};
function CopyMenuItem({
blocks,
onCopy,
label
}) {
const ref = (0, _compose.useCopyToClipboard)(() => (0, _blocks.serialize)(blocks), onCopy);
const copyMenuItemBlocksLabel = blocks.length > 1 ? (0, _i18n.__)('Copy blocks') : (0, _i18n.__)('Copy block');
const copyMenuItemLabel = label ? label : copyMenuItemBlocksLabel;
return (0, _element.createElement)(_components.MenuItem, {
ref: ref
}, copyMenuItemLabel);
}
function BlockSettingsDropdown({
clientIds,
__experimentalSelectBlock,
children,
__unstableDisplayLocation,
...props
}) {
const blockClientIds = Array.isArray(clientIds) ? clientIds : [clientIds];
const count = blockClientIds.length;
const firstBlockClientId = blockClientIds[0];
const {
firstParentClientId,
isDistractionFree,
onlyBlock,
parentBlockType,
previousBlockClientId,
selectedBlockClientIds
} = (0, _data.useSelect)(select => {
const {
getBlockCount,
getBlockName,
getBlockRootClientId,
getPreviousBlockClientId,
getSelectedBlockClientIds,
getSettings,
getBlockAttributes
} = select(_store.store);
const {
getActiveBlockVariation
} = select(_blocks.store);
const _firstParentClientId = getBlockRootClientId(firstBlockClientId);
const parentBlockName = _firstParentClientId && getBlockName(_firstParentClientId);
return {
firstParentClientId: _firstParentClientId,
isDistractionFree: getSettings().isDistractionFree,
onlyBlock: 1 === getBlockCount(_firstParentClientId),
parentBlockType: _firstParentClientId && (getActiveBlockVariation(parentBlockName, getBlockAttributes(_firstParentClientId)) || (0, _blocks.getBlockType)(parentBlockName)),
previousBlockClientId: getPreviousBlockClientId(firstBlockClientId),
selectedBlockClientIds: getSelectedBlockClientIds()
};
}, [firstBlockClientId]);
const {
getBlockOrder,
getSelectedBlockClientIds
} = (0, _data.useSelect)(_store.store);
const shortcuts = (0, _data.useSelect)(select => {
const {
getShortcutRepresentation
} = select(_keyboardShortcuts.store);
return {
duplicate: getShortcutRepresentation('core/block-editor/duplicate'),
remove: getShortcutRepresentation('core/block-editor/remove'),
insertAfter: getShortcutRepresentation('core/block-editor/insert-after'),
insertBefore: getShortcutRepresentation('core/block-editor/insert-before')
};
}, []);
const isMatch = (0, _keyboardShortcuts.__unstableUseShortcutEventMatch)();
const {
selectBlock,
toggleBlockHighlight
} = (0, _data.useDispatch)(_store.store);
const hasSelectedBlocks = selectedBlockClientIds.length > 0;
const updateSelectionAfterDuplicate = (0, _element.useCallback)(async clientIdsPromise => {
if (__experimentalSelectBlock) {
const ids = await clientIdsPromise;
if (ids && ids[0]) {
__experimentalSelectBlock(ids[0], false);
}
}
}, [__experimentalSelectBlock]);
const updateSelectionAfterRemove = (0, _element.useCallback)(() => {
if (__experimentalSelectBlock) {
let blockToFocus = previousBlockClientId || firstParentClientId; // Focus the first block if there's no previous block nor parent block.
if (!blockToFocus) {
blockToFocus = getBlockOrder()[0];
} // Only update the selection if the original selection is removed.
const shouldUpdateSelection = hasSelectedBlocks && getSelectedBlockClientIds().length === 0;
__experimentalSelectBlock(blockToFocus, shouldUpdateSelection);
}
}, [__experimentalSelectBlock, previousBlockClientId, firstParentClientId, getBlockOrder, hasSelectedBlocks, getSelectedBlockClientIds]);
const removeBlockLabel = count === 1 ? (0, _i18n.__)('Delete') : (0, _i18n.__)('Delete blocks'); // Allows highlighting the parent block outline when focusing or hovering
// the parent block selector within the child.
const selectParentButtonRef = (0, _element.useRef)();
const {
gestures: showParentOutlineGestures
} = (0, _utils.useShowMoversGestures)({
ref: selectParentButtonRef,
onChange(isFocused) {
if (isFocused && isDistractionFree) {
return;
}
toggleBlockHighlight(firstParentClientId, isFocused);
}
}); // This can occur when the selected block (the parent)
// displays child blocks within a List View.
const parentBlockIsSelected = selectedBlockClientIds?.includes(firstParentClientId);
return (0, _element.createElement)(_blockActions.default, {
clientIds: clientIds,
__experimentalUpdateSelection: !__experimentalSelectBlock
}, ({
canDuplicate,
canInsertDefaultBlock,
canMove,
canRemove,
onDuplicate,
onInsertAfter,
onInsertBefore,
onRemove,
onCopy,
onPasteStyles,
onMoveTo,
blocks
}) => (0, _element.createElement)(_components.DropdownMenu, (0, _extends2.default)({
icon: _icons.moreVertical,
label: (0, _i18n.__)('Options'),
className: "block-editor-block-settings-menu",
popoverProps: POPOVER_PROPS,
noIcons: true,
menuProps: {
/**
* @param {KeyboardEvent} event
*/
onKeyDown(event) {
if (event.defaultPrevented) return;
if (isMatch('core/block-editor/remove', event) && canRemove) {
event.preventDefault();
updateSelectionAfterRemove(onRemove());
} else if (isMatch('core/block-editor/duplicate', event) && canDuplicate) {
event.preventDefault();
updateSelectionAfterDuplicate(onDuplicate());
} else if (isMatch('core/block-editor/insert-after', event) && canInsertDefaultBlock) {
event.preventDefault();
onInsertAfter();
} else if (isMatch('core/block-editor/insert-before', event) && canInsertDefaultBlock) {
event.preventDefault();
onInsertBefore();
}
}
}
}, props), ({
onClose
}) => (0, _element.createElement)(_element.Fragment, null, (0, _element.createElement)(_components.MenuGroup, null, (0, _element.createElement)(_blockSettingsMenuFirstItem.default.Slot, {
fillProps: {
onClose
}
}), !parentBlockIsSelected && !!firstParentClientId && (0, _element.createElement)(_components.MenuItem, (0, _extends2.default)({}, showParentOutlineGestures, {
ref: selectParentButtonRef,
icon: (0, _element.createElement)(_blockIcon.default, {
icon: parentBlockType.icon
}),
onClick: () => selectBlock(firstParentClientId)
}), (0, _i18n.sprintf)(
/* translators: %s: Name of the block's parent. */
(0, _i18n.__)('Select parent block (%s)'), parentBlockType.title)), count === 1 && (0, _element.createElement)(_blockHtmlConvertButton.default, {
clientId: firstBlockClientId
}), (0, _element.createElement)(CopyMenuItem, {
blocks: blocks,
onCopy: onCopy
}), canDuplicate && (0, _element.createElement)(_components.MenuItem, {
onClick: (0, _compose.pipe)(onClose, onDuplicate, updateSelectionAfterDuplicate),
shortcut: shortcuts.duplicate
}, (0, _i18n.__)('Duplicate')), canInsertDefaultBlock && (0, _element.createElement)(_element.Fragment, null, (0, _element.createElement)(_components.MenuItem, {
onClick: (0, _compose.pipe)(onClose, onInsertBefore),
shortcut: shortcuts.insertBefore
}, (0, _i18n.__)('Add before')), (0, _element.createElement)(_components.MenuItem, {
onClick: (0, _compose.pipe)(onClose, onInsertAfter),
shortcut: shortcuts.insertAfter
}, (0, _i18n.__)('Add after')))), (0, _element.createElement)(_components.MenuGroup, null, (0, _element.createElement)(CopyMenuItem, {
blocks: blocks,
onCopy: onCopy,
label: (0, _i18n.__)('Copy styles')
}), (0, _element.createElement)(_components.MenuItem, {
onClick: onPasteStyles
}, (0, _i18n.__)('Paste styles'))), (0, _element.createElement)(_blockSettingsMenuControls.default.Slot, {
fillProps: {
onClose,
canMove,
onMoveTo,
onlyBlock,
count,
firstBlockClientId
},
clientIds: clientIds,
__unstableDisplayLocation: __unstableDisplayLocation
}), typeof children === 'function' ? children({
onClose
}) : _element.Children.map(child => (0, _element.cloneElement)(child, {
onClose
})), canRemove && (0, _element.createElement)(_components.MenuGroup, null, (0, _element.createElement)(_components.MenuItem, {
onClick: (0, _compose.pipe)(onClose, onRemove, updateSelectionAfterRemove),
shortcut: shortcuts.remove
}, removeBlockLabel)))));
}
var _default = BlockSettingsDropdown;
exports.default = _default;
//# sourceMappingURL=block-settings-dropdown.js.map