UNPKG

@wordpress/block-editor

Version:
128 lines (119 loc) 3.79 kB
/** * External dependencies */ import { map, compact } from 'lodash'; /** * WordPress dependencies */ import { Fragment } from '@wordpress/element'; /** * Internal dependencies */ import BlockNavigationBlock from './block'; import BlockNavigationAppender from './appender'; import { isClientIdSelected } from './utils'; export default function BlockNavigationBranch( props ) { const { blocks, selectBlock, selectedBlockClientIds, showAppender, showBlockMovers, showNestedBlocks, parentBlockClientId, level = 1, terminatedLevels = [], path = [], isBranchSelected = false, isLastOfBranch = false, } = props; const isTreeRoot = ! parentBlockClientId; const filteredBlocks = compact( blocks ); const itemHasAppender = ( parentClientId ) => showAppender && ! isTreeRoot && isClientIdSelected( parentClientId, selectedBlockClientIds ); const hasAppender = itemHasAppender( parentBlockClientId ); // Add +1 to the rowCount to take the block appender into account. const blockCount = filteredBlocks.length; const rowCount = hasAppender ? blockCount + 1 : blockCount; const appenderPosition = rowCount; return ( <> { map( filteredBlocks, ( block, index ) => { const { clientId, innerBlocks } = block; const position = index + 1; const isLastRowAtLevel = rowCount === position; const updatedTerminatedLevels = isLastRowAtLevel ? [ ...terminatedLevels, level ] : terminatedLevels; const updatedPath = [ ...path, position ]; const hasNestedBlocks = showNestedBlocks && !! innerBlocks && !! innerBlocks.length; const hasNestedAppender = itemHasAppender( clientId ); const hasNestedBranch = hasNestedBlocks || hasNestedAppender; const isSelected = isClientIdSelected( clientId, selectedBlockClientIds ); const isSelectedBranch = isBranchSelected || ( isSelected && hasNestedBranch ); // Logic needed to target the last item of a selected branch which might be deeply nested. // This is currently only needed for styling purposes. See: `.is-last-of-selected-branch`. const isLastBlock = index === blockCount - 1; const isLast = isSelected || ( isLastOfBranch && isLastBlock ); const isLastOfSelectedBranch = isLastOfBranch && ! hasNestedBranch && isLastBlock; return ( <Fragment key={ clientId }> <BlockNavigationBlock block={ block } onClick={ selectBlock } isSelected={ isSelected } isBranchSelected={ isSelectedBranch } isLastOfSelectedBranch={ isLastOfSelectedBranch } level={ level } position={ position } rowCount={ rowCount } siblingBlockCount={ blockCount } showBlockMovers={ showBlockMovers } terminatedLevels={ terminatedLevels } path={ updatedPath } /> { hasNestedBranch && ( <BlockNavigationBranch blocks={ innerBlocks } selectedBlockClientIds={ selectedBlockClientIds } selectBlock={ selectBlock } isBranchSelected={ isSelectedBranch } isLastOfBranch={ isLast } showAppender={ showAppender } showBlockMovers={ showBlockMovers } showNestedBlocks={ showNestedBlocks } parentBlockClientId={ clientId } level={ level + 1 } terminatedLevels={ updatedTerminatedLevels } path={ updatedPath } /> ) } </Fragment> ); } ) } { hasAppender && ( <BlockNavigationAppender parentBlockClientId={ parentBlockClientId } position={ rowCount } rowCount={ appenderPosition } level={ level } terminatedLevels={ terminatedLevels } path={ [ ...path, appenderPosition ] } /> ) } </> ); } BlockNavigationBranch.defaultProps = { selectBlock: () => {}, };