@wordpress/block-editor
Version:
148 lines (122 loc) • 4.83 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _element = require("@wordpress/element");
var _classnames = _interopRequireDefault(require("classnames"));
var _data = require("@wordpress/data");
var _blocks = require("@wordpress/blocks");
var _defaultBlockAppender = _interopRequireDefault(require("../default-block-appender"));
var _buttonBlockAppender = _interopRequireDefault(require("../button-block-appender"));
var _store = require("../../store");
var _lockUnlock = require("../../lock-unlock");
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function DefaultAppender({
rootClientId
}) {
const canInsertDefaultBlock = (0, _data.useSelect)(select => select(_store.store).canInsertBlockType((0, _blocks.getDefaultBlockName)(), rootClientId));
if (canInsertDefaultBlock) {
// Render the default block appender if the context supports use
// of the default appender.
return (0, _element.createElement)(_defaultBlockAppender.default, {
rootClientId: rootClientId
});
} // Fallback in case the default block can't be inserted.
return (0, _element.createElement)(_buttonBlockAppender.default, {
rootClientId: rootClientId,
className: "block-list-appender__toggle"
});
}
function useAppender(rootClientId, CustomAppender) {
const {
hideInserter,
isParentSelected
} = (0, _data.useSelect)(select => {
const {
getTemplateLock,
getSelectedBlockClientId,
__unstableGetEditorMode,
getBlockEditingMode
} = (0, _lockUnlock.unlock)(select(_store.store));
const selectedBlockClientId = getSelectedBlockClientId();
return {
hideInserter: !!getTemplateLock(rootClientId) || getBlockEditingMode(rootClientId) === 'disabled' || __unstableGetEditorMode() === 'zoom-out',
isParentSelected: rootClientId === selectedBlockClientId || !rootClientId && !selectedBlockClientId
};
}, [rootClientId]);
if (hideInserter || CustomAppender === false) {
return null;
}
if (CustomAppender) {
// Prefer custom render prop if provided.
return (0, _element.createElement)(CustomAppender, null);
}
if (!isParentSelected) {
return null;
}
return (0, _element.createElement)(DefaultAppender, {
rootClientId: rootClientId
});
}
function BlockListAppender({
rootClientId,
renderAppender,
className,
tagName: TagName = 'div'
}) {
const appender = useAppender(rootClientId, renderAppender);
const isDragOver = (0, _data.useSelect)(select => {
const {
getBlockInsertionPoint,
isBlockInsertionPointVisible,
getBlockCount
} = select(_store.store);
const insertionPoint = getBlockInsertionPoint(); // Ideally we should also check for `isDragging` but currently it
// requires a lot more setup. We can revisit this once we refactor
// the DnD utility hooks.
return isBlockInsertionPointVisible() && rootClientId === insertionPoint?.rootClientId && getBlockCount(rootClientId) === 0;
}, [rootClientId]);
if (!appender) {
return null;
}
return (0, _element.createElement)(TagName // A `tabIndex` is used on the wrapping `div` element in order to
// force a focus event to occur when an appender `button` element
// is clicked. In some browsers (Firefox, Safari), button clicks do
// not emit a focus event, which could cause this event to propagate
// unexpectedly. The `tabIndex` ensures that the interaction is
// captured as a focus, without also adding an extra tab stop.
//
// See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
, {
tabIndex: -1,
className: (0, _classnames.default)('block-list-appender wp-block', className, {
'is-drag-over': isDragOver
}) // Needed in case the whole editor is content editable (for multi
// selection). It fixes an edge case where ArrowDown and ArrowRight
// should collapse the selection to the end of that selection and
// not into the appender.
,
contentEditable: false // The appender exists to let you add the first Paragraph before
// any is inserted. To that end, this appender should visually be
// presented as a block. That means theme CSS should style it as if
// it were an empty paragraph block. That means a `wp-block` class to
// ensure the width is correct, and a [data-block] attribute to ensure
// the correct margin is applied, especially for classic themes which
// have commonly targeted that attribute for margins.
,
"data-block": true
}, appender);
}
var _default = BlockListAppender;
exports.default = _default;
//# sourceMappingURL=index.js.map