Skip to content

Commit

Permalink
Show outline on parent blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad authored and Joen Asmussen committed May 16, 2018
1 parent 80dffb5 commit 839eb28
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 13 deletions.
17 changes: 12 additions & 5 deletions editor/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ export class BlockListBlock extends Component {
isMultiSelecting,
hoverArea,
isLargeViewport,
hasSelectedInnerBlock,
} = this.props;
const isHovered = this.state.isHovered && ! isMultiSelecting;
const { name: blockName, isValid } = block;
Expand All @@ -424,14 +425,14 @@ export class BlockListBlock extends Component {
// If the block is selected and we're typing the block should not appear.
// Empty paragraph blocks should always show up as unselected.
const isEmptyDefaultBlock = isUnmodifiedDefaultBlock( block );
const isSelectedNotTyping = isSelected && ! isTypingWithinBlock;
const showEmptyBlockSideInserter = ( isSelected || isHovered ) && isEmptyDefaultBlock;
const shouldAppearSelected = ! showEmptyBlockSideInserter && isSelectedNotTyping;
const showSideInserter = ( isSelected || isHovered ) && isEmptyDefaultBlock;
const shouldAppearSelected = ! showSideInserter && ( isSelected || hasSelectedInnerBlock ) && ! isTypingWithinBlock;
// We render block movers and block settings to keep them tabbale even if hidden
const shouldRenderMovers = ( isSelected || hoverArea === 'left' ) && ! showEmptyBlockSideInserter && ! isMultiSelecting && ! isMultiSelected && ! isTypingWithinBlock;
const shouldRenderBlockSettings = ( isSelected || hoverArea === 'right' ) && ! isMultiSelecting && ! isMultiSelected && ! isTypingWithinBlock;
const shouldShowBreadcrumb = isHovered;
const shouldShowContextualToolbar = shouldAppearSelected && isValid && ( ! hasFixedToolbar || ! isLargeViewport );
const shouldShowContextualToolbar = ! showSideInserter && isSelected && ! isTypingWithinBlock && isValid && ( ! hasFixedToolbar || ! isLargeViewport );
const shouldShowMobileToolbar = shouldAppearSelected;
const { error, dragging } = this.state;

Expand Down Expand Up @@ -623,8 +624,11 @@ const applyWithSelect = withSelect( ( select, { uid, rootUID } ) => {
getSelectedBlocksInitialCaretPosition,
getBlockSelectionEnd,
getEditorSettings,
getBlockRootUID,
hasSelectedInnerBlock,
} = select( 'core/editor' );
const isSelected = isBlockSelected( uid );
const isParentOfSelectedBlock = hasSelectedInnerBlock( uid );
const { templateLock, hasFixedToolbar } = getEditorSettings();

return {
Expand All @@ -635,17 +639,20 @@ const applyWithSelect = withSelect( ( select, { uid, rootUID } ) => {
isFirstMultiSelected: isFirstMultiSelectedBlock( uid ),
isMultiSelecting: isMultiSelecting(),
isLastInSelection: getBlockSelectionEnd() === uid,
hasSelectedInnerBlock: isParentOfSelectedBlock,
// We only care about this prop when the block is selected
// Thus to avoid unnecessary rerenders we avoid updating the prop if the block is not selected.
isTypingWithinBlock: isSelected && isTyping(),
isTypingWithinBlock: ( isSelected || isParentOfSelectedBlock ) && isTyping(),
order: getBlockIndex( uid, rootUID ),
meta: getEditedPostAttribute( 'meta' ),
mode: getBlockMode( uid ),
isSelectionEnabled: isSelectionEnabled(),
initialPosition: getSelectedBlocksInitialCaretPosition(),
isSelected,
isLocked: !! templateLock,
hasFixedToolbar,
rootUIDOfRoot: getBlockRootUID( rootUID ),
orderOfRoot: getBlockIndex( rootUID, getBlockRootUID( rootUID ) ),
isSelected,
};
} );

Expand Down
9 changes: 2 additions & 7 deletions editor/components/block-list/breadcrumb.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@ import classnames from 'classnames';
* WordPress dependencies
*/
import { compose, Component } from '@wordpress/element';
<<<<<<< HEAD
import { IconButton, Toolbar } from '@wordpress/components';
=======
import { Button, Tooltip, Toolbar } from '@wordpress/components';
>>>>>>> Polish the breadcrumb, tweak paddings
import { Toolbar } from '@wordpress/components';
import { withDispatch, withSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
Expand Down Expand Up @@ -57,7 +52,7 @@ export class BlockBreadcrumb extends Component {
}

render( ) {
const { uid, rootUID, selectRootBlock, isHidden } = this.props;
const { uid, rootUID, isHidden } = this.props;
const { isFocused } = this.state;

return (
Expand Down
22 changes: 21 additions & 1 deletion editor/components/block-list/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,15 @@
z-index: z-index( '.editor-block-list__block {core/image aligned wide or fullwide}' );
}

// Wide
&[data-align="wide"] {
// compensate for main container padding
@include break-small() {
margin-left: $block-side-ui-padding;
margin-right: $block-side-ui-padding;
}
}

// Full-wide
&[data-align="full"] {

Expand Down Expand Up @@ -337,7 +346,7 @@
border-right-width: 0;
}

// Mover and settings in wide
// Mover and settings in full-wide
> .editor-block-mover,
> .editor-block-settings-menu {
top: -29px;
Expand All @@ -364,6 +373,17 @@
float: left;
}

// There is no side UI clearance on fullwide elements, so they are simply not draggable on the sides
> .editor-block-list__block-draggable {
left: 0;
right: 0;
}

// Position hover label on the right
> .editor-block-list__breadcrumb {
right: 0;
}

// Hide mover until wide breakpoints, or it might be covered by toolbar
> .editor-block-mover {
display: none;
Expand Down
13 changes: 13 additions & 0 deletions editor/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
includes,
values,
castArray,
some,
} from 'lodash';
import createSelector from 'rememo';

Expand Down Expand Up @@ -934,6 +935,18 @@ export function isBlockSelected( state, uid ) {
return start === uid;
}

/**
* Returns true if one of the block's inner blocks is selected.
*
* @param {Object} state Global application state.
* @param {string} uid Block unique ID.
*
* @return {boolean} Whether the block as an inner block selected
*/
export function hasSelectedInnerBlock( state, uid ) {
return some( getBlockOrder( state, uid ), ( innerUID ) => isBlockSelected( state, innerUID ) );
}

/**
* Returns true if the block corresponding to the specified unique ID is
* currently selected but isn't the last of the selected blocks. Here "last"
Expand Down
33 changes: 33 additions & 0 deletions editor/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const {
getPreviousBlockUid,
getNextBlockUid,
isBlockSelected,
hasSelectedInnerBlock,
isBlockWithinSelection,
hasMultiSelection,
isBlockMultiSelected,
Expand Down Expand Up @@ -2051,6 +2052,38 @@ describe( 'selectors', () => {
} );
} );

describe( 'hasSelectedInnerBlock', () => {
it( 'should return false if the selected block is a child of the given UID', () => {
const state = {
blockSelection: { start: 5, end: 5 },
editor: {
present: {
blockOrder: {
4: [ 3, 2, 1 ],
},
},
},
};

expect( hasSelectedInnerBlock( state, 4 ) ).toBe( false );
} );

it( 'should return true if the selected block is a child of the given UID', () => {
const state = {
blockSelection: { start: 3, end: 3 },
editor: {
present: {
blockOrder: {
4: [ 3, 2, 1 ],
},
},
},
};

expect( hasSelectedInnerBlock( state, 4 ) ).toBe( true );
} );
} );

describe( 'isBlockWithinSelection', () => {
it( 'should return true if the block is selected but not the last', () => {
const state = {
Expand Down

0 comments on commit 839eb28

Please sign in to comment.