@gechiui/block-editor
Version:
171 lines (140 loc) • 5.46 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _element = require("@gechiui/element");
var _lodash = require("lodash");
var _data = require("@gechiui/data");
var _block = _interopRequireDefault(require("./block"));
var _context = require("./context");
var _utils = require("./utils");
/**
* External dependencies
*/
/**
* GeChiUI dependencies
*/
/**
* Internal dependencies
*/
/**
* Given a block, returns the total number of blocks in that subtree. This is used to help determine
* the list position of a block.
*
* When a block is collapsed, we do not count their children as part of that total. In the current drag
* implementation dragged blocks and their children are not counted.
*
* @param {Object} block block tree
* @param {Object} expandedState state that notes which branches are collapsed
* @param {Array} draggedClientIds a list of dragged client ids
* @return {number} block count
*/
function countBlocks(block, expandedState, draggedClientIds) {
var _expandedState$block$;
const isDragged = draggedClientIds === null || draggedClientIds === void 0 ? void 0 : draggedClientIds.includes(block.clientId);
if (isDragged) {
return 0;
}
const isExpanded = (_expandedState$block$ = expandedState[block.clientId]) !== null && _expandedState$block$ !== void 0 ? _expandedState$block$ : true;
if (isExpanded) {
return 1 + block.innerBlocks.reduce(countReducer(expandedState, draggedClientIds), 0);
}
return 1;
}
const countReducer = (expandedState, draggedClientIds) => (count, block) => {
var _expandedState$block$2;
const isDragged = draggedClientIds === null || draggedClientIds === void 0 ? void 0 : draggedClientIds.includes(block.clientId);
if (isDragged) {
return count;
}
const isExpanded = (_expandedState$block$2 = expandedState[block.clientId]) !== null && _expandedState$block$2 !== void 0 ? _expandedState$block$2 : true;
if (isExpanded && block.innerBlocks.length > 0) {
return count + countBlocks(block, expandedState, draggedClientIds);
}
return count + 1;
};
function ListViewBranch(props) {
const {
blocks,
selectBlock,
showBlockMovers,
showNestedBlocks,
selectedClientIds,
level = 1,
path = '',
isBranchSelected = false,
listPosition = 0,
fixedListWindow
} = props;
const {
expandedState,
draggedClientIds,
__experimentalPersistentListViewFeatures
} = (0, _context.useListViewContext)();
const filteredBlocks = (0, _lodash.compact)(blocks);
const blockCount = filteredBlocks.length;
let nextPosition = listPosition;
return (0, _element.createElement)(_element.Fragment, null, filteredBlocks.map((block, index) => {
var _expandedState$client;
const {
clientId,
innerBlocks
} = block;
if (index > 0) {
nextPosition += countBlocks(filteredBlocks[index - 1], expandedState, draggedClientIds);
}
const usesWindowing = __experimentalPersistentListViewFeatures;
const {
itemInView
} = fixedListWindow;
const blockInView = !usesWindowing || itemInView(nextPosition);
const position = index + 1;
const updatedPath = path.length > 0 ? `${path}_${position}` : `${position}`;
const hasNestedBlocks = showNestedBlocks && !!innerBlocks && !!innerBlocks.length;
const isExpanded = hasNestedBlocks ? (_expandedState$client = expandedState[clientId]) !== null && _expandedState$client !== void 0 ? _expandedState$client : true : undefined;
const isDragged = !!(draggedClientIds !== null && draggedClientIds !== void 0 && draggedClientIds.includes(clientId));
const showBlock = isDragged || blockInView; // Make updates to the selected or dragged blocks synchronous,
// but asynchronous for any other block.
const isSelected = (0, _utils.isClientIdSelected)(clientId, selectedClientIds);
const isSelectedBranch = isBranchSelected || isSelected && hasNestedBlocks;
return (0, _element.createElement)(_data.AsyncModeProvider, {
key: clientId,
value: !isSelected
}, showBlock && (0, _element.createElement)(_block.default, {
block: block,
selectBlock: selectBlock,
isSelected: isSelected,
isBranchSelected: isSelectedBranch,
isDragged: isDragged,
level: level,
position: position,
rowCount: blockCount,
siblingBlockCount: blockCount,
showBlockMovers: showBlockMovers,
path: updatedPath,
isExpanded: isExpanded,
listPosition: nextPosition
}), !showBlock && (0, _element.createElement)("tr", null, (0, _element.createElement)("td", {
className: "block-editor-list-view-placeholder"
})), hasNestedBlocks && isExpanded && !isDragged && (0, _element.createElement)(ListViewBranch, {
blocks: innerBlocks,
selectBlock: selectBlock,
showBlockMovers: showBlockMovers,
showNestedBlocks: showNestedBlocks,
level: level + 1,
path: updatedPath,
listPosition: nextPosition + 1,
fixedListWindow: fixedListWindow,
isBranchSelected: isSelectedBranch,
selectedClientIds: selectedClientIds
}));
}));
}
ListViewBranch.defaultProps = {
selectBlock: () => {}
};
var _default = (0, _element.memo)(ListViewBranch);
exports.default = _default;
//# sourceMappingURL=branch.js.map