@gechiui/block-editor
Version:
199 lines (171 loc) • 6.83 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _element = require("@gechiui/element");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _compose = require("@gechiui/compose");
var _components = require("@gechiui/components");
var _data = require("@gechiui/data");
var _i18n = require("@gechiui/i18n");
var _branch = _interopRequireDefault(require("./branch"));
var _context = require("./context");
var _dropIndicator = _interopRequireDefault(require("./drop-indicator"));
var _useListViewClientIds = _interopRequireDefault(require("./use-list-view-client-ids"));
var _useListViewDropZone = _interopRequireDefault(require("./use-list-view-drop-zone"));
var _store = require("../../store");
/**
* GeChiUI dependencies
*/
/**
* Internal dependencies
*/
const noop = () => {};
const expanded = (state, action) => {
switch (action.type) {
case 'expand':
return { ...state,
...{
[action.clientId]: true
}
};
case 'collapse':
return { ...state,
...{
[action.clientId]: false
}
};
default:
return state;
}
};
/**
* Wrap `ListViewRows` with `TreeGrid`. ListViewRows is a
* recursive component (it renders itself), so this ensures TreeGrid is only
* present at the very top of the navigation grid.
*
* @param {Object} props Components props.
* @param {Array} props.blocks Custom subset of block client IDs to be used instead of the default hierarchy.
* @param {Function} props.onSelect Block selection callback.
* @param {boolean} props.showNestedBlocks Flag to enable displaying nested blocks.
* @param {boolean} props.showBlockMovers Flag to enable block movers
* @param {boolean} props.__experimentalFeatures Flag to enable experimental features.
* @param {boolean} props.__experimentalPersistentListViewFeatures Flag to enable features for the Persistent List View experiment.
* @param {boolean} props.__experimentalHideContainerBlockActions Flag to hide actions of top level blocks (like core/widget-area)
* @param {Object} ref Forwarded ref
*/
function ListView(_ref, ref) {
let {
blocks,
onSelect = noop,
__experimentalFeatures,
__experimentalPersistentListViewFeatures,
__experimentalHideContainerBlockActions,
showNestedBlocks,
showBlockMovers,
...props
} = _ref;
const {
clientIdsTree,
draggedClientIds,
selectedClientIds
} = (0, _useListViewClientIds.default)(blocks);
const {
selectBlock
} = (0, _data.useDispatch)(_store.store);
const {
visibleBlockCount
} = (0, _data.useSelect)(select => {
const {
getGlobalBlockCount,
getClientIdsOfDescendants
} = select(_store.store);
const draggedBlockCount = (draggedClientIds === null || draggedClientIds === void 0 ? void 0 : draggedClientIds.length) > 0 ? getClientIdsOfDescendants(draggedClientIds).length + 1 : 0;
return {
visibleBlockCount: getGlobalBlockCount() - draggedBlockCount
};
}, [draggedClientIds]);
const selectEditorBlock = (0, _element.useCallback)(clientId => {
selectBlock(clientId);
onSelect(clientId);
}, [selectBlock, onSelect]);
const [expandedState, setExpandedState] = (0, _element.useReducer)(expanded, {});
const {
ref: dropZoneRef,
target: blockDropTarget
} = (0, _useListViewDropZone.default)();
const elementRef = (0, _element.useRef)();
const treeGridRef = (0, _compose.useMergeRefs)([elementRef, dropZoneRef, ref]);
const isMounted = (0, _element.useRef)(false);
(0, _element.useEffect)(() => {
isMounted.current = true;
}, []); // List View renders a fixed number of items and relies on each having a fixed item height of 36px.
// If this value changes, we should also change the itemHeight value set in useFixedWindowList.
// See: https://github.com/GeChiUI/gutenberg/pull/35230 for additional context.
const [fixedListWindow] = (0, _compose.__experimentalUseFixedWindowList)(elementRef, 36, visibleBlockCount, {
useWindowing: __experimentalPersistentListViewFeatures,
windowOverscan: 40
});
const expand = (0, _element.useCallback)(clientId => {
if (!clientId) {
return;
}
setExpandedState({
type: 'expand',
clientId
});
}, [setExpandedState]);
const collapse = (0, _element.useCallback)(clientId => {
if (!clientId) {
return;
}
setExpandedState({
type: 'collapse',
clientId
});
}, [setExpandedState]);
const expandRow = (0, _element.useCallback)(row => {
var _row$dataset;
expand(row === null || row === void 0 ? void 0 : (_row$dataset = row.dataset) === null || _row$dataset === void 0 ? void 0 : _row$dataset.block);
}, [expand]);
const collapseRow = (0, _element.useCallback)(row => {
var _row$dataset2;
collapse(row === null || row === void 0 ? void 0 : (_row$dataset2 = row.dataset) === null || _row$dataset2 === void 0 ? void 0 : _row$dataset2.block);
}, [collapse]);
const contextValue = (0, _element.useMemo)(() => ({
__experimentalFeatures,
__experimentalPersistentListViewFeatures,
__experimentalHideContainerBlockActions,
isTreeGridMounted: isMounted.current,
draggedClientIds,
expandedState,
expand,
collapse
}), [__experimentalFeatures, __experimentalPersistentListViewFeatures, __experimentalHideContainerBlockActions, isMounted.current, draggedClientIds, expandedState, expand, collapse]);
return (0, _element.createElement)(_data.AsyncModeProvider, {
value: true
}, (0, _element.createElement)(_dropIndicator.default, {
listViewRef: elementRef,
blockDropTarget: blockDropTarget
}), (0, _element.createElement)(_components.__experimentalTreeGrid, {
className: "block-editor-list-view-tree",
"aria-label": (0, _i18n.__)('区块导航结构'),
ref: treeGridRef,
onCollapseRow: collapseRow,
onExpandRow: expandRow
}, (0, _element.createElement)(_context.ListViewContext.Provider, {
value: contextValue
}, (0, _element.createElement)(_branch.default, (0, _extends2.default)({
blocks: clientIdsTree,
selectBlock: selectEditorBlock,
showNestedBlocks: showNestedBlocks,
showBlockMovers: showBlockMovers,
fixedListWindow: fixedListWindow,
selectedClientIds: selectedClientIds
}, props)))));
}
var _default = (0, _element.forwardRef)(ListView);
exports.default = _default;
//# sourceMappingURL=index.js.map