@gechiui/block-editor
Version:
312 lines (272 loc) • 8.25 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import { createElement } from "@gechiui/element";
/**
* External dependencies
*/
import { size } from 'lodash';
import classnames from 'classnames';
/**
* GeChiUI dependencies
*/
import { speak } from '@gechiui/a11y';
import { __, _x, sprintf } from '@gechiui/i18n';
import { Dropdown, Button } from '@gechiui/components';
import { Component } from '@gechiui/element';
import { withDispatch, withSelect } from '@gechiui/data';
import { compose, ifCondition } from '@gechiui/compose';
import { createBlock, store as blocksStore } from '@gechiui/blocks';
import { plus } from '@gechiui/icons';
/**
* Internal dependencies
*/
import InserterMenu from './menu';
import QuickInserter from './quick-inserter';
import { store as blockEditorStore } from '../../store';
const defaultRenderToggle = _ref => {
let {
onToggle,
disabled,
isOpen,
blockTitle,
hasSingleBlockType,
toggleProps = {}
} = _ref;
let label;
if (hasSingleBlockType) {
label = sprintf( // translators: %s: the name of the block when there is only one
_x('Add %s', 'directly add the only allowed block'), blockTitle);
} else {
label = _x('Add block', 'Generic label for block inserter button');
}
const {
onClick,
...rest
} = toggleProps; // Handle both onClick functions from the toggle and the parent component
function handleClick(event) {
if (onToggle) {
onToggle(event);
}
if (onClick) {
onClick(event);
}
}
return createElement(Button, _extends({
icon: plus,
label: label,
tooltipPosition: "bottom",
onClick: handleClick,
className: "block-editor-inserter__toggle",
"aria-haspopup": !hasSingleBlockType ? 'true' : false,
"aria-expanded": !hasSingleBlockType ? isOpen : false,
disabled: disabled
}, rest));
};
class Inserter extends Component {
constructor() {
super(...arguments);
this.onToggle = this.onToggle.bind(this);
this.renderToggle = this.renderToggle.bind(this);
this.renderContent = this.renderContent.bind(this);
}
onToggle(isOpen) {
const {
onToggle
} = this.props; // Surface toggle callback to parent component
if (onToggle) {
onToggle(isOpen);
}
}
/**
* Render callback to display Dropdown toggle element.
*
* @param {Object} options
* @param {Function} options.onToggle Callback to invoke when toggle is
* pressed.
* @param {boolean} options.isOpen Whether dropdown is currently open.
*
* @return {GCElement} Dropdown toggle element.
*/
renderToggle(_ref2) {
let {
onToggle,
isOpen
} = _ref2;
const {
disabled,
blockTitle,
hasSingleBlockType,
directInsertBlock,
toggleProps,
hasItems,
renderToggle = defaultRenderToggle
} = this.props;
return renderToggle({
onToggle,
isOpen,
disabled: disabled || !hasItems,
blockTitle,
hasSingleBlockType,
directInsertBlock,
toggleProps
});
}
/**
* Render callback to display Dropdown content element.
*
* @param {Object} options
* @param {Function} options.onClose Callback to invoke when dropdown is
* closed.
*
* @return {GCElement} Dropdown content element.
*/
renderContent(_ref3) {
let {
onClose
} = _ref3;
const {
rootClientId,
clientId,
isAppender,
showInserterHelpPanel,
// This prop is experimental to give some time for the quick inserter to mature
// Feel free to make them stable after a few releases.
__experimentalIsQuick: isQuick
} = this.props;
if (isQuick) {
return createElement(QuickInserter, {
onSelect: () => {
onClose();
},
rootClientId: rootClientId,
clientId: clientId,
isAppender: isAppender
});
}
return createElement(InserterMenu, {
onSelect: () => {
onClose();
},
rootClientId: rootClientId,
clientId: clientId,
isAppender: isAppender,
showInserterHelpPanel: showInserterHelpPanel
});
}
render() {
const {
position,
hasSingleBlockType,
directInsertBlock,
insertOnlyAllowedBlock,
__experimentalIsQuick: isQuick,
onSelectOrClose
} = this.props;
if (hasSingleBlockType || directInsertBlock !== null && directInsertBlock !== void 0 && directInsertBlock.length) {
return this.renderToggle({
onToggle: insertOnlyAllowedBlock
});
}
return createElement(Dropdown, {
className: "block-editor-inserter",
contentClassName: classnames('block-editor-inserter__popover', {
'is-quick': isQuick
}),
position: position,
onToggle: this.onToggle,
expandOnMobile: true,
headerTitle: __('添加区块'),
renderToggle: this.renderToggle,
renderContent: this.renderContent,
onClose: onSelectOrClose
});
}
}
export default compose([withSelect((select, _ref4) => {
let {
clientId,
rootClientId
} = _ref4;
const {
getBlockRootClientId,
hasInserterItems,
__experimentalGetAllowedBlocks,
__experimentalGetDirectInsertBlock
} = select(blockEditorStore);
const {
getBlockVariations
} = select(blocksStore);
rootClientId = rootClientId || getBlockRootClientId(clientId) || undefined;
const allowedBlocks = __experimentalGetAllowedBlocks(rootClientId);
const directInsertBlock = __experimentalGetDirectInsertBlock(rootClientId);
const hasSingleBlockType = size(allowedBlocks) === 1 && size(getBlockVariations(allowedBlocks[0].name, 'inserter')) === 0;
let allowedBlockType = false;
if (hasSingleBlockType) {
allowedBlockType = allowedBlocks[0];
}
return {
hasItems: hasInserterItems(rootClientId),
hasSingleBlockType,
blockTitle: allowedBlockType ? allowedBlockType.title : '',
allowedBlockType,
directInsertBlock,
rootClientId
};
}), withDispatch((dispatch, ownProps, _ref5) => {
let {
select
} = _ref5;
return {
insertOnlyAllowedBlock() {
const {
rootClientId,
clientId,
isAppender,
hasSingleBlockType,
allowedBlockType,
directInsertBlock,
onSelectOrClose
} = ownProps;
if (!hasSingleBlockType && !(directInsertBlock !== null && directInsertBlock !== void 0 && directInsertBlock.length)) {
return;
}
function getInsertionIndex() {
const {
getBlockIndex,
getBlockSelectionEnd,
getBlockOrder,
getBlockRootClientId
} = select(blockEditorStore); // If the clientId is defined, we insert at the position of the block.
if (clientId) {
return getBlockIndex(clientId);
} // If there a selected block, we insert after the selected block.
const end = getBlockSelectionEnd();
if (!isAppender && end && getBlockRootClientId(end) === rootClientId) {
return getBlockIndex(end) + 1;
} // Otherwise, we insert at the end of the current rootClientId
return getBlockOrder(rootClientId).length;
}
const {
insertBlock
} = dispatch(blockEditorStore);
const blockToInsert = directInsertBlock !== null && directInsertBlock !== void 0 && directInsertBlock.length ? createBlock(...directInsertBlock) : createBlock(allowedBlockType.name);
insertBlock(blockToInsert, getInsertionIndex(), rootClientId);
if (onSelectOrClose) {
onSelectOrClose();
}
const message = sprintf( // translators: %s: the name of the block that has been added
__('%s区块已添加'), allowedBlockType.title);
speak(message);
}
};
}), // The global inserter should always be visible, we are using ( ! isAppender && ! rootClientId && ! clientId ) as
// a way to detect the global Inserter.
ifCondition(_ref6 => {
let {
hasItems,
isAppender,
rootClientId,
clientId
} = _ref6;
return hasItems || !isAppender && !rootClientId && !clientId;
})])(Inserter);
//# sourceMappingURL=index.js.map