From 44ca18f859076efca6fc2f8b217d8cb26c45d154 Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Mon, 30 Apr 2018 13:17:47 +0200 Subject: [PATCH 01/14] Alternate hover approach WIP --- edit-post/assets/stylesheets/_animations.scss | 2 +- edit-post/assets/stylesheets/_variables.scss | 9 +- edit-post/assets/stylesheets/_z-index.scss | 1 + editor/components/block-list/breadcrumb.js | 13 +- editor/components/block-list/style.scss | 268 +++++++++++------- editor/components/block-toolbar/style.scss | 7 +- 6 files changed, 178 insertions(+), 122 deletions(-) diff --git a/edit-post/assets/stylesheets/_animations.scss b/edit-post/assets/stylesheets/_animations.scss index efed0d8a238c0e..b908255ab54501 100644 --- a/edit-post/assets/stylesheets/_animations.scss +++ b/edit-post/assets/stylesheets/_animations.scss @@ -27,6 +27,6 @@ } @mixin fade_in { - animation: fade-in 0.3s ease-out; + animation: fade-in 0.2s ease-out; animation-fill-mode: forwards; } diff --git a/edit-post/assets/stylesheets/_variables.scss b/edit-post/assets/stylesheets/_variables.scss index 51f5ad40d269a8..f8376591492f65 100644 --- a/edit-post/assets/stylesheets/_variables.scss +++ b/edit-post/assets/stylesheets/_variables.scss @@ -43,12 +43,17 @@ $inserter-tabs-height: 36px; $block-toolbar-height: 37px; // Blocks +$parent-block-padding: 32px; $block-padding: 14px; -$block-mover-margin: 18px; -$block-spacing: 4px; + +$parent-block-side-ui-padding: 56px; $block-side-ui-padding: 36px; + $block-side-ui-width: 28px; // The side UI max height matches a single line of text, 56px. 28px is half, allowing 2 mover arrows $block-side-ui-clearance: 2px; +$block-parent-side-ui-clearance: 18px; + +$block-spacing: 4px; // Buttons & UI Widgets $button-style__radius-roundrect: 4px; diff --git a/edit-post/assets/stylesheets/_z-index.scss b/edit-post/assets/stylesheets/_z-index.scss index e20891d9740e41..0fe811011e6bce 100644 --- a/edit-post/assets/stylesheets/_z-index.scss +++ b/edit-post/assets/stylesheets/_z-index.scss @@ -9,6 +9,7 @@ $z-layers: ( '.editor-block-list__block {core/image aligned left or right}': 20, '.editor-block-list__block {core/image aligned wide or fullwide}': 20, '.freeform-toolbar': 10, + '.editor-block-list__breadcrumb': 1, '.editor-warning': 1, '.components-form-toggle__input': 1, '.editor-inserter__tabs': 1, diff --git a/editor/components/block-list/breadcrumb.js b/editor/components/block-list/breadcrumb.js index 528e69db07330a..ade9d453a26bb2 100644 --- a/editor/components/block-list/breadcrumb.js +++ b/editor/components/block-list/breadcrumb.js @@ -7,7 +7,11 @@ 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 { withDispatch, withSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; @@ -62,14 +66,9 @@ export class BlockBreadcrumb extends Component { } ) }> { rootUID && ( - + ) } + { rootUID && ( ) } diff --git a/editor/components/block-list/style.scss b/editor/components/block-list/style.scss index 5f6a7ad8f819dc..2de840337a72c0 100644 --- a/editor/components/block-list/style.scss +++ b/editor/components/block-list/style.scss @@ -1,11 +1,16 @@ -.components-draggable__clone { +.editor-block-list__layout .components-draggable__clone { & > .editor-block-list__block > .editor-block-list__block-draggable { background: $white; // @todo: ensure this works with themes that invert the color box-shadow: $shadow-popover; @include break-small { - left: 0; - right: 0; + left: -$block-parent-side-ui-clearance - 1px; + right: -$block-parent-side-ui-clearance - 1px; + + .editor-block-list__layout & { + left: -1px; + right: -1px; + } } } @@ -19,7 +24,7 @@ } } -.editor-block-list__block-draggable { +.editor-block-list__layout .editor-block-list__block-draggable { position: absolute; top: 0; right: 0; @@ -52,8 +57,15 @@ } @include break-small { - left: -$block-side-ui-padding; - right: -$block-side-ui-padding; + // use a wider available space for hovering/selecting/dragging on top level blocks + left: -$parent-block-padding - $block-padding; + right: -$parent-block-padding - $block-padding; + + // use smaller space for hovering/selecting/dragging on child blocks + .editor-block-list__layout & { + left: -$block-side-ui-width; + right: -$block-side-ui-width; + } // Full width blocks don't have the place to expand on the side .editor-block-list__block[data-align="full"] & { @@ -104,6 +116,10 @@ } } +/** + * General layout + */ + .editor-block-list__layout .editor-block-list__block { position: relative; padding-left: $block-padding; @@ -181,56 +197,8 @@ } /** - * Hovered Block style + * Block outline layout */ - - &.is-selected > .editor-block-mover:before, - &.is-hovered > .editor-block-mover:before, - &.is-selected > .editor-block-settings-menu:before, - &.is-hovered > .editor-block-settings-menu:before { - content: ''; - position: absolute; - height: 36px; - top: 10px; - } - - &.is-hovered > .editor-block-mover:before { - right: 0; - - // use opacity to work in various editor styles - border-right: 1px solid $dark-opacity-light-500; - - .is-dark-theme & { - border-right-color: $light-opacity-light-500; - } - } - - &.is-hovered > .editor-block-settings-menu:before { - left: 0; - - // use opacity to work in various editor styles - border-left: 1px solid $dark-opacity-light-500; - - .is-dark-theme & { - border-left-color: $light-opacity-light-500; - } - } - - &.is-typing .editor-block-list__empty-block-inserter, - &.is-typing .editor-block-list__side-inserter { - opacity: 0; - } - - .editor-block-list__empty-block-inserter, - .editor-block-list__side-inserter { - opacity: 1; - transition: opacity 0.2s; - } - - /** - * Selected Block style - */ - .editor-block-list__block-edit { position: relative; @@ -238,30 +206,51 @@ z-index: z-index( '.editor-block-list__block-edit:before' ); content: ''; position: absolute; + outline: 1px solid transparent; + transition: outline .1s linear; + pointer-events: none; + + // show wider padding for top level blocks + right: -$parent-block-padding; + left: -$parent-block-padding; top: -$block-padding; - right: -$block-padding; bottom: -$block-padding; + } + + // show smaller padding for child blocks + .editor-block-list__block-edit:before { + right: -$block-padding; left: -$block-padding; - outline: 1px solid transparent; - pointer-events: none; + top: -$block-padding; + bottom: -$block-padding; } + } + + // Hover style + &.is-hovered > .editor-block-list__block-edit:before { + outline: 1px solid $blue-medium-300; } - // focused block-style + // Selected style &.is-selected > .editor-block-list__block-edit:before { // use opacity to work in various editor styles outline: 1px solid $dark-opacity-light-500; + top: -$block-padding; + bottom: -$block-padding; .is-dark-theme & { outline-color: $light-opacity-light-500; } } +} - /** - * Selection Style - */ +/** + * Cross-block selection + */ + +.editor-block-list__layout .editor-block-list__block { ::-moz-selection { background-color: $blue-medium-highlight; } @@ -281,23 +270,60 @@ // use opacity to work in various editor styles mix-blend-mode: multiply; + // Collapse extra vertical padding on selection + top: -$block-padding; + bottom: -$block-padding; + .is-dark-theme & { mix-blend-mode: soft-light; } } +} - /** - * Shared blocks - */ - &.is-shared > .editor-block-mover:before { - border-right: none; +/** + * Block styles and alignments + */ + +.editor-block-list__layout .editor-block-list__block { + + // Warnings + &.has-warning .editor-block-list__block-edit { + position: relative; + min-height: 250px; + max-height: 500px; + overflow: hidden; + + > :not( .editor-warning ) { + pointer-events: none; + user-select: none; + } } - &.is-shared > .editor-block-settings-menu:before { - border-left: none; + &.has-warning .editor-block-list__block-edit:after { + content: ''; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: rgba( $white, 0.6 ); + background-image: linear-gradient( to bottom, transparent, $white ); } + // Appender + &.is-typing .editor-block-list__empty-block-inserter, + &.is-typing .editor-block-list__side-inserter { + opacity: 0; + } + + .editor-block-list__empty-block-inserter, + .editor-block-list__side-inserter { + opacity: 1; + transition: opacity 0.2s; + } + + // Shared blocks &.is-shared > .editor-block-list__block-edit:before { // use opacity to work in various editor styles outline: 1px dashed $dark-opacity-light-500; @@ -307,10 +333,7 @@ } } - /** - * Alignments - */ - + // Alignments &[data-align="left"], &[data-align="right"] { // Without z-index, won't be clickable as "above" adjacent content @@ -448,8 +471,8 @@ > .editor-block-settings-menu, > .editor-block-mover { position: absolute; - top: 0; // stretch to bottom to utilize full vertical space to increase hoverable area - bottom: 0; + top: 0; + min-height: 50%; // stretch to fill half of the available space to increase hoverable area width: $block-side-ui-width + $block-side-ui-clearance; /* Necessary for drag indicator */ @@ -471,9 +494,16 @@ // Right side UI > .editor-block-settings-menu { - right: -$block-side-ui-width - $block-side-ui-clearance; padding-left: $block-side-ui-clearance; + // Position for top level blocks + right: -$block-side-ui-width - $block-side-ui-clearance - $block-parent-side-ui-clearance; + + // Position for nested blocks + .editor-block-list__block & { + right: -$block-side-ui-width - $block-side-ui-clearance; + } + // Mobile display: none; @include break-small() { @@ -484,9 +514,16 @@ // Left side UI > .editor-block-mover { - left: -$block-side-ui-width - $block-side-ui-clearance; padding-right: $block-side-ui-clearance; + // Position for top level blocks + left: -$block-side-ui-width - $block-side-ui-clearance - $block-parent-side-ui-clearance; + + // Position for nested blocks + .editor-block-list__block & { + left: -$block-side-ui-width - $block-side-ui-clearance; + } + // Mobile display: none; @include break-small() { @@ -589,11 +626,11 @@ background: $white; height: $block-padding * 2 + 8px; width: $block-padding * 2 + 8px; - + &:not(:disabled):not([aria-disabled="true"]):hover { box-shadow: none; } - + } // Show a line indicator when hovering, but this is unclickable @@ -649,8 +686,8 @@ * Block Toolbar */ -.editor-block-contextual-toolbar, -.editor-block-list__breadcrumb { + .editor-block-list__block .editor-block-contextual-toolbar { + position: sticky; z-index: z-index( '.editor-block-contextual-toolbar' ); white-space: nowrap; text-align: left; @@ -692,8 +729,14 @@ @include break-small() { // stack borders - margin-left: -$block-padding - $block-side-ui-padding - 1px; - margin-right: -$block-padding - $block-side-ui-padding - 1px; + margin-left: -$block-padding - $block-side-ui-padding - $block-parent-side-ui-clearance - 1px; + margin-right: -$block-padding - $block-side-ui-padding - $block-parent-side-ui-clearance - 1px; + + // fixme nested + .editor-block-list__block & { + margin-left: -$block-padding - $block-side-ui-padding - 1px; + margin-right: -$block-padding - $block-side-ui-padding - 1px; + } // except for wide elements, this causes a horizontal scrollbar [data-align="full"] & { @@ -709,8 +752,7 @@ } -.editor-block-contextual-toolbar .editor-block-toolbar, -.editor-block-list__breadcrumb .components-toolbar { +.editor-block-contextual-toolbar .editor-block-toolbar { width: 100%; background: $white; @@ -733,27 +775,39 @@ } } -.editor-block-list__breadcrumb .components-toolbar { - padding: 0px 12px; - line-height: $block-toolbar-height - 1px; - font-family: $default-font; - font-size: $default-font-size; - color: $dark-gray-500; - cursor: default; - - .components-button { - margin-left: -12px; - margin-right: 12px; - border-right: 1px solid $light-gray-500; - color: $dark-gray-500; - padding-top: 6px; - } -} - -.editor-block-list__breadcrumb { - opacity: 0; - - &.is-visible { - @include fade_in; +/** + * Hover label + */ + .editor-block-list__breadcrumb { + position: absolute; + line-height: 1; + background: rgba( $white, .7 ); + padding: 0px 4px 2px 4px; + z-index: z-index( '.editor-block-list__breadcrumb' ); + + // Position in the top right of the border + right: -$block-parent-side-ui-clearance - 1px; + top: -$block-padding - 4px; + background-color: $blue-medium-300; + + // Nested + .editor-block-list__block-edit & { + right: $parent-block-padding - $block-padding - $block-parent-side-ui-clearance - 1px; + } + + .components-toolbar { + padding: 0; + border: none; + background: transparent; + padding: 0px; + line-height: 1; + font-family: $default-font; + font-size: 11px; + color: $white; + cursor: default; + + > span { + margin: 0 4px; + } } } diff --git a/editor/components/block-toolbar/style.scss b/editor/components/block-toolbar/style.scss index c615ffadab7e98..550baff733b493 100644 --- a/editor/components/block-toolbar/style.scss +++ b/editor/components/block-toolbar/style.scss @@ -13,7 +13,7 @@ .components-toolbar { border: none; - border-left: 1px solid $light-gray-500; + border-left: 1px solid $light-gray-700; } // this should probably have its own class @@ -24,8 +24,5 @@ .editor-block-toolbar .editor-block-switcher { display: inline-flex; - - .edit-post-header-toolbar__block-toolbar & { - border-left-color: 1px solid $light-gray-500; - } + border-left: 1px solid $light-gray-700; } From 12be2f935aad77a462899db0b452009b62795166 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 4 May 2018 11:16:00 +0100 Subject: [PATCH 02/14] Show outline on parent blocks --- editor/components/block-list/block.js | 15 +++++-- editor/components/block-list/breadcrumb.js | 9 +--- editor/components/block-list/style.scss | 48 ++++++++++++++++++---- editor/components/block-toolbar/style.scss | 1 - editor/store/selectors.js | 13 ++++++ editor/store/test/selectors.js | 33 +++++++++++++++ 6 files changed, 99 insertions(+), 20 deletions(-) diff --git a/editor/components/block-list/block.js b/editor/components/block-list/block.js index b8b46799ab96c6..21437b80afbb65 100644 --- a/editor/components/block-list/block.js +++ b/editor/components/block-list/block.js @@ -413,6 +413,7 @@ export class BlockListBlock extends Component { isLargeViewport, isEmptyDefaultBlock, isPreviousBlockADefaultEmptyBlock, + hasSelectedInnerBlock, } = this.props; const isHovered = this.state.isHovered && ! isMultiSelecting; const { name: blockName, isValid } = block; @@ -426,12 +427,13 @@ export class BlockListBlock extends Component { // Empty paragraph blocks should always show up as unselected. 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; @@ -620,8 +622,11 @@ const applyWithSelect = withSelect( ( select, { uid, rootUID } ) => { isSelectionEnabled, getSelectedBlocksInitialCaretPosition, getEditorSettings, + getBlockRootUID, + hasSelectedInnerBlock, } = select( 'core/editor' ); const isSelected = isBlockSelected( uid ); + const isParentOfSelectedBlock = hasSelectedInnerBlock( uid ); const { templateLock, hasFixedToolbar } = getEditorSettings(); const block = getBlock( uid ); const previousBlockUid = getPreviousBlockUid( uid ); @@ -632,9 +637,10 @@ const applyWithSelect = withSelect( ( select, { uid, rootUID } ) => { isMultiSelected: isBlockMultiSelected( uid ), isFirstMultiSelected: isFirstMultiSelectedBlock( uid ), isMultiSelecting: isMultiSelecting(), + 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 ), @@ -647,6 +653,9 @@ const applyWithSelect = withSelect( ( select, { uid, rootUID } ) => { block, isSelected, hasFixedToolbar, + rootUIDOfRoot: getBlockRootUID( rootUID ), + orderOfRoot: getBlockIndex( rootUID, getBlockRootUID( rootUID ) ), + isSelected, }; } ); diff --git a/editor/components/block-list/breadcrumb.js b/editor/components/block-list/breadcrumb.js index ade9d453a26bb2..a130f206a09494 100644 --- a/editor/components/block-list/breadcrumb.js +++ b/editor/components/block-list/breadcrumb.js @@ -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 @@ -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 ( diff --git a/editor/components/block-list/style.scss b/editor/components/block-list/style.scss index 2de840337a72c0..6f068b32fb517b 100644 --- a/editor/components/block-list/style.scss +++ b/editor/components/block-list/style.scss @@ -378,6 +378,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"] { @@ -409,11 +418,12 @@ border-right-width: 0; } - // Mover and settings in wide + // Mover and settings in full-wide > .editor-block-mover, > .editor-block-settings-menu { - top: -29px; + top: -$block-side-ui-width - 1px; // move upwards the height of the button +1px for border bottom: auto; + min-height: 0; height: auto; width: auto; z-index: inherit; @@ -429,6 +439,8 @@ > .editor-block-settings-menu { right: 10px; + width: $block-side-ui-width * 2; + flex-direction: row; } > .editor-block-mover .editor-block-mover__control, @@ -436,6 +448,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; @@ -653,13 +676,20 @@ } } -.editor-block-list__block > .editor-block-list__insertion-point { - position: absolute; - top: -$block-padding - $block-spacing / 2; - height: $block-padding * 2; // Matches the whole empty space between two blocks - bottom: auto; - left: -1px; - right: -1px; +.editor-block-list__block { + > .editor-block-list__insertion-point { + position: absolute; + top: -$block-padding - $block-spacing / 2; + height: $block-padding * 2; // Matches the whole empty space between two blocks + bottom: auto; + left: -1px; + right: -1px; + } + + &[data-align="full"] > .editor-block-list__insertion-point { + left: 0; + right: 0; + } } .editor-block-list__block .editor-block-list__block-html-textarea { diff --git a/editor/components/block-toolbar/style.scss b/editor/components/block-toolbar/style.scss index 550baff733b493..5bcff6f5444b83 100644 --- a/editor/components/block-toolbar/style.scss +++ b/editor/components/block-toolbar/style.scss @@ -24,5 +24,4 @@ .editor-block-toolbar .editor-block-switcher { display: inline-flex; - border-left: 1px solid $light-gray-700; } diff --git a/editor/store/selectors.js b/editor/store/selectors.js index bff45b02f0f62e..87d621c4fa1bfc 100644 --- a/editor/store/selectors.js +++ b/editor/store/selectors.js @@ -15,6 +15,7 @@ import { orderBy, reduce, size, + some, } from 'lodash'; import createSelector from 'rememo'; @@ -935,6 +936,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" diff --git a/editor/store/test/selectors.js b/editor/store/test/selectors.js index 734195a03b7f4c..dc681a1719132b 100644 --- a/editor/store/test/selectors.js +++ b/editor/store/test/selectors.js @@ -58,6 +58,7 @@ const { getPreviousBlockUid, getNextBlockUid, isBlockSelected, + hasSelectedInnerBlock, isBlockWithinSelection, hasMultiSelection, isBlockMultiSelected, @@ -2083,6 +2084,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 = { From aa2ea9faadbf44be591035010d391bf6ecf1d92e Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 24 May 2018 12:10:17 -0400 Subject: [PATCH 03/14] Block List: Remove unused variables --- editor/components/block-list/block.js | 5 ----- editor/components/block-list/breadcrumb.js | 18 ++++++------------ 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/editor/components/block-list/block.js b/editor/components/block-list/block.js index 21437b80afbb65..fa6fa18dea7246 100644 --- a/editor/components/block-list/block.js +++ b/editor/components/block-list/block.js @@ -425,7 +425,6 @@ 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 isSelectedNotTyping = isSelected && ! isTypingWithinBlock; const showEmptyBlockSideInserter = ( isSelected || isHovered ) && isEmptyDefaultBlock; const showSideInserter = ( isSelected || isHovered ) && isEmptyDefaultBlock; const shouldAppearSelected = ! showSideInserter && ( isSelected || hasSelectedInnerBlock ) && ! isTypingWithinBlock; @@ -622,7 +621,6 @@ const applyWithSelect = withSelect( ( select, { uid, rootUID } ) => { isSelectionEnabled, getSelectedBlocksInitialCaretPosition, getEditorSettings, - getBlockRootUID, hasSelectedInnerBlock, } = select( 'core/editor' ); const isSelected = isBlockSelected( uid ); @@ -653,9 +651,6 @@ const applyWithSelect = withSelect( ( select, { uid, rootUID } ) => { block, isSelected, hasFixedToolbar, - rootUIDOfRoot: getBlockRootUID( rootUID ), - orderOfRoot: getBlockIndex( rootUID, getBlockRootUID( rootUID ) ), - isSelected, }; } ); diff --git a/editor/components/block-list/breadcrumb.js b/editor/components/block-list/breadcrumb.js index a130f206a09494..1d916d6dbd2b85 100644 --- a/editor/components/block-list/breadcrumb.js +++ b/editor/components/block-list/breadcrumb.js @@ -6,9 +6,9 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { compose, Component } from '@wordpress/element'; +import { compose, Component, Fragment } from '@wordpress/element'; import { Toolbar } from '@wordpress/components'; -import { withDispatch, withSelect } from '@wordpress/data'; +import { withSelect } from '@wordpress/data'; /** * Internal dependencies @@ -61,9 +61,11 @@ export class BlockBreadcrumb extends Component { } ) }> { rootUID && ( - + + + + ) } - { rootUID && ( ) } @@ -80,12 +82,4 @@ export default compose( [ rootUID: getBlockRootUID( uid ), }; } ), - withDispatch( ( dispatch, ownProps ) => { - const { rootUID } = ownProps; - const { selectBlock } = dispatch( 'core/editor' ); - - return { - selectRootBlock: () => selectBlock( rootUID ), - }; - } ), ] )( BlockBreadcrumb ); From 62d412eba17842c3c471ea1ab2312d18e5cf9f3a Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 24 May 2018 08:54:52 -0400 Subject: [PATCH 04/14] Block Breadcrumb: Render arrow as RTL compatible --- editor/components/block-list/breadcrumb.js | 2 +- editor/components/block-list/style.scss | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/editor/components/block-list/breadcrumb.js b/editor/components/block-list/breadcrumb.js index 1d916d6dbd2b85..d82553898eb8de 100644 --- a/editor/components/block-list/breadcrumb.js +++ b/editor/components/block-list/breadcrumb.js @@ -63,7 +63,7 @@ export class BlockBreadcrumb extends Component { { rootUID && ( - + ) } diff --git a/editor/components/block-list/style.scss b/editor/components/block-list/style.scss index 6f068b32fb517b..feee1f850300c3 100644 --- a/editor/components/block-list/style.scss +++ b/editor/components/block-list/style.scss @@ -835,9 +835,15 @@ font-size: 11px; color: $white; cursor: default; + } +} - > span { - margin: 0 4px; - } +.editor-block-list__descendant-arrow:before { + content: '→'; + display: inline-block; + padding: 0 4px; + + .rtl & { + content: '←'; } } From 1d2ca61fc00367850d331f51e35fff036f0deec6 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 24 May 2018 12:09:01 -0400 Subject: [PATCH 05/14] Writing Flow: Force tab stop at focusable wrapper when inner blocks exist --- editor/components/writing-flow/index.js | 16 ++++- editor/utils/dom.js | 12 ++++ editor/utils/test/dom.js | 37 ++++++++++ .../__snapshots__/writing-flow.test.js.snap | 23 +++++++ test/e2e/specs/writing-flow.test.js | 67 +++++++++++++++++++ 5 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 editor/utils/test/dom.js create mode 100644 test/e2e/specs/__snapshots__/writing-flow.test.js.snap create mode 100644 test/e2e/specs/writing-flow.test.js diff --git a/editor/components/writing-flow/index.js b/editor/components/writing-flow/index.js index abc3f24f78003a..57136104602de9 100644 --- a/editor/components/writing-flow/index.js +++ b/editor/components/writing-flow/index.js @@ -27,6 +27,7 @@ import './style.scss'; import { isBlockFocusStop, isInSameBlock, + hasInnerBlocksContext, } from '../../utils/dom'; /** @@ -105,11 +106,22 @@ class WritingFlow extends Component { return false; } - // Prefer text fields, but settle for block focus stop. - if ( ! isTextField( node ) && ! isBlockFocusStop( node ) ) { + // Prefer text fields... + if ( isTextField( node ) ) { + return true; + } + + // ...but settle for block focus stop. + if ( ! isBlockFocusStop( node ) ) { return false; } + // If element contains inner blocks, stop immediately at its focus + // wrapper. + if ( hasInnerBlocksContext( node ) ) { + return true; + } + // If navigating out of a block (in reverse), don't consider its // block focus stop. if ( node.contains( target ) ) { diff --git a/editor/utils/dom.js b/editor/utils/dom.js index 28f27a9d51e1af..6fc736ccdb9e2d 100644 --- a/editor/utils/dom.js +++ b/editor/utils/dom.js @@ -52,3 +52,15 @@ export function isBlockFocusStop( element ) { export function isInSameBlock( a, b ) { return a.closest( '[data-block]' ) === b.closest( '[data-block]' ); } + +/** + * Returns true if the given HTMLElement contains inner blocks (an InnerBlocks + * element). + * + * @param {HTMLElement} element Element to test. + * + * @return {boolean} Whether element contains inner blocks. + */ +export function hasInnerBlocksContext( element ) { + return !! element.querySelector( '.editor-block-list__layout' ); +} diff --git a/editor/utils/test/dom.js b/editor/utils/test/dom.js new file mode 100644 index 00000000000000..69be43576373f3 --- /dev/null +++ b/editor/utils/test/dom.js @@ -0,0 +1,37 @@ +/** + * Internal dependencies + */ +import { hasInnerBlocksContext } from '../dom'; + +describe( 'hasInnerBlocksContext()', () => { + it( 'should return false for a block node which has no inner blocks', () => { + const wrapper = document.createElement( 'div' ); + wrapper.innerHTML = ( + '
' + + '
' + + '

This is a test.

' + + '
' + + '
' + ); + + const blockNode = wrapper.firstChild; + expect( hasInnerBlocksContext( blockNode ) ).toBe( false ); + } ); + + it( 'should return true for a block node which contains inner blocks', () => { + const wrapper = document.createElement( 'div' ); + wrapper.innerHTML = ( + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + ); + + const blockNode = wrapper.firstChild; + expect( hasInnerBlocksContext( blockNode ) ).toBe( true ); + } ); +} ); diff --git a/test/e2e/specs/__snapshots__/writing-flow.test.js.snap b/test/e2e/specs/__snapshots__/writing-flow.test.js.snap new file mode 100644 index 00000000000000..e9ad304b10799f --- /dev/null +++ b/test/e2e/specs/__snapshots__/writing-flow.test.js.snap @@ -0,0 +1,23 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`adding blocks Should navigate inner blocks with arrow keys 1`] = ` +" +

First paragraph

+ + + +
+ +

First column paragraph

+ + + +

Second column paragraph

+ +
+ + + +

Second paragraph

+" +`; diff --git a/test/e2e/specs/writing-flow.test.js b/test/e2e/specs/writing-flow.test.js new file mode 100644 index 00000000000000..70665c8e2f1921 --- /dev/null +++ b/test/e2e/specs/writing-flow.test.js @@ -0,0 +1,67 @@ +/** + * Internal dependencies + */ +import '../support/bootstrap'; +import { + newPost, + newDesktopBrowserPage, + getHTMLFromCodeEditor, +} from '../support/utils'; + +describe( 'adding blocks', () => { + beforeAll( async () => { + await newDesktopBrowserPage(); + } ); + + beforeEach( async () => { + await newPost(); + } ); + + it( 'Should navigate inner blocks with arrow keys', async () => { + let activeElementText; + + // Add demo content + await page.click( '.editor-default-block-appender__content' ); + await page.keyboard.type( 'First paragraph' ); + await page.keyboard.press( 'Enter' ); + await page.keyboard.type( '/columns' ); + await page.keyboard.press( 'Enter' ); + await page.keyboard.type( 'First column paragraph' ); + + // Arrow down should navigate through layouts in columns block (to + // its default appender). + await page.keyboard.press( 'ArrowDown' ); + await page.keyboard.type( 'Second column paragraph' ); + + // Arrow down from last of layouts exits nested context to default + // appender of root level. + await page.keyboard.press( 'ArrowDown' ); + await page.keyboard.type( 'Second paragraph' ); + + // Arrow up into nested context focuses last text input + await page.keyboard.press( 'ArrowUp' ); + activeElementText = await page.evaluate( () => document.activeElement.textContent ); + expect( activeElementText ).toBe( 'Second column paragraph' ); + + // Arrow up in inner blocks should navigate through text fields. + await page.keyboard.press( 'ArrowUp' ); + activeElementText = await page.evaluate( () => document.activeElement.textContent ); + expect( activeElementText ).toBe( 'First column paragraph' ); + + // Arrow up from first text field in nested context focuses wrapper + // before escaping out. + await page.keyboard.press( 'ArrowUp' ); + const activeElementBlockType = await page.evaluate( () => ( + document.activeElement.getAttribute( 'data-type' ) + ) ); + expect( activeElementBlockType ).toBe( 'core/columns' ); + + // Arrow up from focused (columns) block wrapper exits nested context + // to prior text input. + await page.keyboard.press( 'ArrowUp' ); + activeElementText = await page.evaluate( () => document.activeElement.textContent ); + expect( activeElementText ).toBe( 'First paragraph' ); + + expect( await getHTMLFromCodeEditor() ).toMatchSnapshot(); + } ); +} ); From a31b30d83997a0fab9578effac735dbce606f35b Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 24 May 2018 13:22:08 -0400 Subject: [PATCH 06/14] Inner Blocks: Show overlay for small screen, unselected root block --- core-blocks/columns/style.scss | 9 ++-- edit-post/assets/stylesheets/_animations.scss | 4 +- edit-post/assets/stylesheets/_z-index.scss | 8 ++++ editor/components/block-edit/index.js | 2 + editor/components/block-list/breadcrumb.js | 12 +---- editor/components/block-list/style.scss | 25 +++++----- editor/components/block-mover/style.scss | 13 +++--- .../components/block-settings-menu/style.scss | 15 ++++-- editor/components/block-toolbar/style.scss | 4 ++ .../default-block-appender/style.scss | 2 +- editor/components/inner-blocks/index.js | 46 +++++++++++++++++-- editor/components/inner-blocks/style.scss | 9 ++++ 12 files changed, 110 insertions(+), 39 deletions(-) create mode 100644 editor/components/inner-blocks/style.scss diff --git a/core-blocks/columns/style.scss b/core-blocks/columns/style.scss index 9ec2e09c5c8753..32b99fd0bc6583 100644 --- a/core-blocks/columns/style.scss +++ b/core-blocks/columns/style.scss @@ -1,9 +1,12 @@ .wp-block-columns { - display: grid; - grid-auto-flow: dense; + + .editor-inner-blocks { + display: grid; + grid-auto-flow: dense; + } @for $i from 2 through 6 { - &.has-#{ $i }-columns { + &.has-#{ $i }-columns .editor-inner-blocks { grid-auto-columns: #{ 100% / $i }; } } diff --git a/edit-post/assets/stylesheets/_animations.scss b/edit-post/assets/stylesheets/_animations.scss index b908255ab54501..b3068ec3bc3424 100644 --- a/edit-post/assets/stylesheets/_animations.scss +++ b/edit-post/assets/stylesheets/_animations.scss @@ -26,7 +26,7 @@ animation: slide_in_right 0.1s forwards; } -@mixin fade_in { - animation: fade-in 0.2s ease-out; +@mixin fade_in( $speed: 0.2s ) { + animation: fade-in $speed ease-out; animation-fill-mode: forwards; } diff --git a/edit-post/assets/stylesheets/_z-index.scss b/edit-post/assets/stylesheets/_z-index.scss index 0fe811011e6bce..180c5a94774104 100644 --- a/edit-post/assets/stylesheets/_z-index.scss +++ b/edit-post/assets/stylesheets/_z-index.scss @@ -27,6 +27,10 @@ $z-layers: ( '.core-blocks-button__inline-link .editor-url-input__suggestions': 6, // URL suggestions for button block above sibling inserter '.wp-block-image__resize-handlers': 1, // Resize handlers above sibling inserter + // Side UI active buttons + '.editor-block-settings-remove': 1, + '.editor-block-mover__control': 1, + // Should have lower index than anything else positioned inside the block containers '.editor-block-list__block-draggable': 0, @@ -45,6 +49,10 @@ $z-layers: ( // should overlap most block content. '.editor-block-list__block.is-{selected,hovered} .editor-block-{settings-menu,mover}': 80, + // Small screen inner blocks overlay must be displayed above drop zone, + // settings menu, and movers. + '.editor-inner-blocks__small-screen-overlay:after': 120, + // Show sidebar above wp-admin navigation bar for mobile viewports: // #wpadminbar { z-index: 99999 } '.edit-post-sidebar': 100000, diff --git a/editor/components/block-edit/index.js b/editor/components/block-edit/index.js index c5a6c2bcf2dd81..a0ab798ef575bf 100644 --- a/editor/components/block-edit/index.js +++ b/editor/components/block-edit/index.js @@ -34,6 +34,7 @@ export class BlockEdit extends Component { } = this.props; return { + uid, BlockList: createInnerBlockList( uid ), canUserUseUnfilteredHTML: get( user.data, [ 'capabilities', @@ -76,6 +77,7 @@ export class BlockEdit extends Component { } BlockEdit.childContextTypes = { + uid: noop, BlockList: noop, canUserUseUnfilteredHTML: noop, }; diff --git a/editor/components/block-list/breadcrumb.js b/editor/components/block-list/breadcrumb.js index d82553898eb8de..128c6c98617a3f 100644 --- a/editor/components/block-list/breadcrumb.js +++ b/editor/components/block-list/breadcrumb.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - /** * WordPress dependencies */ @@ -52,13 +47,10 @@ export class BlockBreadcrumb extends Component { } render( ) { - const { uid, rootUID, isHidden } = this.props; - const { isFocused } = this.state; + const { uid, rootUID } = this.props; return ( -
+
{ rootUID && ( diff --git a/editor/components/block-list/style.scss b/editor/components/block-list/style.scss index feee1f850300c3..baccc9f2fd6d29 100644 --- a/editor/components/block-list/style.scss +++ b/editor/components/block-list/style.scss @@ -226,12 +226,6 @@ } } - - // Hover style - &.is-hovered > .editor-block-list__block-edit:before { - outline: 1px solid $blue-medium-300; - } - // Selected style &.is-selected > .editor-block-list__block-edit:before { // use opacity to work in various editor styles @@ -243,6 +237,11 @@ outline-color: $light-opacity-light-500; } } + + // Hover style + &.is-hovered > .editor-block-list__block-edit:before { + outline: 1px solid $blue-medium-300; + } } @@ -811,14 +810,11 @@ .editor-block-list__breadcrumb { position: absolute; line-height: 1; - background: rgba( $white, .7 ); - padding: 0px 4px 2px 4px; z-index: z-index( '.editor-block-list__breadcrumb' ); // Position in the top right of the border right: -$block-parent-side-ui-clearance - 1px; - top: -$block-padding - 4px; - background-color: $blue-medium-300; + top: -1px; // Nested .editor-block-list__block-edit & { @@ -833,8 +829,15 @@ line-height: 1; font-family: $default-font; font-size: 11px; - color: $white; cursor: default; + background: rgba( $white, .8 ); + border: 1px solid $blue-medium-300; + padding: 2px 4px; + + // Animate in + .editor-block-list__block:hover & { + @include fade_in( .1s ); + } } } diff --git a/editor/components/block-mover/style.scss b/editor/components/block-mover/style.scss index 9242aa5f7a0774..b467fe8f76793a 100644 --- a/editor/components/block-mover/style.scss +++ b/editor/components/block-mover/style.scss @@ -47,15 +47,16 @@ @include break-small() { .editor-block-list__layout .editor-block-list__layout & { background: $white; - border-color: $light-gray-500; - border-style: solid; - border-width: 1px; + box-shadow: inset 0 0 0 1px $light-gray-500; &:first-child { - border-width: 1px 1px 0 1px; + margin-bottom: -1px; } - &:last-child { - border-width: 0 1px 1px 1px; + + &:hover, + &:active, + &:focus { + z-index: z-index( '.editor-block-mover__control' ); } } } diff --git a/editor/components/block-settings-menu/style.scss b/editor/components/block-settings-menu/style.scss index d94791e0328eef..dfad9afba418d2 100644 --- a/editor/components/block-settings-menu/style.scss +++ b/editor/components/block-settings-menu/style.scss @@ -1,4 +1,5 @@ .editor-block-settings-menu { + line-height: 1; opacity: 0; &.is-visible { @@ -26,10 +27,18 @@ @include break-small() { .editor-block-list__layout .editor-block-list__layout & { background: $white; - border-color: $light-gray-500; - border-style: solid; - border-width: 1px; + box-shadow: inset 0 0 0 1px $light-gray-500; color: $dark-gray-500; // always show dark gray in nested contexts + + &:first-child { + margin-bottom: -1px; + } + + &:hover, + &:active, + &:focus { + z-index: z-index( '.editor-block-settings-remove' ); + } } } } diff --git a/editor/components/block-toolbar/style.scss b/editor/components/block-toolbar/style.scss index 5bcff6f5444b83..495f9690ad9eda 100644 --- a/editor/components/block-toolbar/style.scss +++ b/editor/components/block-toolbar/style.scss @@ -13,6 +13,10 @@ .components-toolbar { border: none; + } + + // Only show the left border if the Switcher is present + .editor-block-switcher + div > .components-toolbar { border-left: 1px solid $light-gray-700; } diff --git a/editor/components/default-block-appender/style.scss b/editor/components/default-block-appender/style.scss index d1e83c312784f5..66d14d99f5492b 100644 --- a/editor/components/default-block-appender/style.scss +++ b/editor/components/default-block-appender/style.scss @@ -74,7 +74,7 @@ $empty-paragraph-height: $text-editor-font-size * 4; right: $item-spacing; // show on the right on mobile @include break-small { - left: -$block-side-ui-padding; + left: -$parent-block-side-ui-padding; right: auto; } diff --git a/editor/components/inner-blocks/index.js b/editor/components/inner-blocks/index.js index 6b1d56c44932db..04399b3dcbe615 100644 --- a/editor/components/inner-blocks/index.js +++ b/editor/components/inner-blocks/index.js @@ -1,13 +1,53 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ import { withContext } from '@wordpress/components'; +import { withViewportMatch } from '@wordpress/viewport'; +import { compose } from '@wordpress/element'; +import { withSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import './style.scss'; -function InnerBlocks( { BlockList, layouts, allowedBlocks, template } ) { - return ; +function InnerBlocks( { + BlockList, + layouts, + allowedBlocks, + template, + isSmallScreen, + isSelectedBlockInRoot, +} ) { + const classes = classnames( 'editor-inner-blocks', { + 'has-overlay': isSmallScreen && ! isSelectedBlockInRoot, + } ); + + return ( +
+ +
+ ); } -InnerBlocks = withContext( 'BlockList' )()( InnerBlocks ); +InnerBlocks = compose( [ + withContext( 'BlockList' )(), + withContext( 'uid' )(), + withViewportMatch( { isSmallScreen: '< medium' } ), + withSelect( ( select, ownProps ) => { + const { isBlockSelected, hasSelectedInnerBlock } = select( 'core/editor' ); + const { uid } = ownProps; + + return { + isSelectedBlockInRoot: isBlockSelected( uid ) || hasSelectedInnerBlock( uid ), + }; + } ), +] )( InnerBlocks ); InnerBlocks.Content = ( { BlockContent } ) => { return ; diff --git a/editor/components/inner-blocks/style.scss b/editor/components/inner-blocks/style.scss new file mode 100644 index 00000000000000..90190c6afc5a72 --- /dev/null +++ b/editor/components/inner-blocks/style.scss @@ -0,0 +1,9 @@ +.editor-inner-blocks.has-overlay:after { + content: ''; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: z-index( '.editor-inner-blocks__small-screen-overlay:after' ); +} From 7488a9633a1f61f09a12c2ffa09c5dcc7738af5d Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Tue, 29 May 2018 13:42:09 +0200 Subject: [PATCH 07/14] Try a refined approach to drag and drop This commit changes how drag and drop works, so that nested blocks do not have any invisible side affordance for the grabby handle. You can still use the inner padding for dragging, and in a separate enhancement we should make the hover label draggable. This makes it easier to select the parent block, by allowing you to click the available space below the side UI to select the parent. Kinda. There is still an affordance for hovering the side of the block to access the side UI (movers, settings, trash), and this extends the height of 4 stacked buttons on the side. If you hover the area below that, yes you can click the thing below. This is a balancing act, and I'd like for you to try this. The branch has been thoroughly rebased and squashed prior to this to make it easy to undo this change if it doesn't feel right. --- edit-post/assets/stylesheets/_mixins.scss | 15 -- edit-post/assets/stylesheets/_variables.scss | 19 ++- edit-post/components/visual-editor/style.scss | 8 +- editor/components/block-list/style.scss | 128 +++++++++--------- .../default-block-appender/style.scss | 2 +- editor/components/post-title/style.scss | 9 +- 6 files changed, 84 insertions(+), 97 deletions(-) diff --git a/edit-post/assets/stylesheets/_mixins.scss b/edit-post/assets/stylesheets/_mixins.scss index badee2f7d96c8f..14c3f41ecb5f67 100644 --- a/edit-post/assets/stylesheets/_mixins.scss +++ b/edit-post/assets/stylesheets/_mixins.scss @@ -101,21 +101,6 @@ } } -/** - * Editor Width mixin - * - * This mixin seeks to take the vinegar out of the responsive alignments in the editor. - */ - -@mixin editor-width( $width ) { - @media ( min-width: #{ ( $width ) } ) { - @content; - } -} - -$content-width-padding: $content-width + $block-side-ui-padding + $block-side-ui-padding; -$float-margin: calc( 50% - #{ $content-width-padding / 2 } ); - /** * Button states and focus styles */ diff --git a/edit-post/assets/stylesheets/_variables.scss b/edit-post/assets/stylesheets/_variables.scss index f8376591492f65..de0e6270ff0474 100644 --- a/edit-post/assets/stylesheets/_variables.scss +++ b/edit-post/assets/stylesheets/_variables.scss @@ -43,17 +43,14 @@ $inserter-tabs-height: 36px; $block-toolbar-height: 37px; // Blocks -$parent-block-padding: 32px; -$block-padding: 14px; - -$parent-block-side-ui-padding: 56px; -$block-side-ui-padding: 36px; - -$block-side-ui-width: 28px; // The side UI max height matches a single line of text, 56px. 28px is half, allowing 2 mover arrows -$block-side-ui-clearance: 2px; -$block-parent-side-ui-clearance: 18px; - -$block-spacing: 4px; +$parent-block-padding: 28px; // padding of top level blocks, should be larger than $block-padding, otherwise a user can't select the parent from a child +$block-padding: 14px; // padding of nested blocks +$block-spacing: 4px; // vertical space between blocks + +$block-side-ui-width: 28px; // width of the side UI, matches half matches half of a single line of text, so two buttons stacke matches 1 +$block-side-ui-clearance: 2px; // space between side UI and block +$block-side-ui-padding: $block-side-ui-width + $block-side-ui-clearance; // total space used to accommodate side UI +$block-parent-side-ui-clearance: $parent-block-padding - $block-padding; // space between side UI and block on top level blocks // Buttons & UI Widgets $button-style__radius-roundrect: 4px; diff --git a/edit-post/components/visual-editor/style.scss b/edit-post/components/visual-editor/style.scss index c9f53c3e977f62..75e9a154646a86 100644 --- a/edit-post/components/visual-editor/style.scss +++ b/edit-post/components/visual-editor/style.scss @@ -45,8 +45,8 @@ @include break-small() { .editor-block-list__block-edit { - margin-left: -$block-side-ui-padding; - margin-right: -$block-side-ui-padding; + margin-left: -$block-side-ui-width; + margin-right: -$block-side-ui-width; } &[data-align="full"] > .editor-block-contextual-toolbar, @@ -87,8 +87,8 @@ // include space for side UI on desktops @include break-small() { > div { - margin-left: -$block-side-ui-padding - 1px; - margin-right: -$block-side-ui-padding - 1px; + margin-left: -$block-side-ui-width; + margin-right: -$block-side-ui-width; } } } diff --git a/editor/components/block-list/style.scss b/editor/components/block-list/style.scss index baccc9f2fd6d29..e875a64a04f1e6 100644 --- a/editor/components/block-list/style.scss +++ b/editor/components/block-list/style.scss @@ -63,8 +63,8 @@ // use smaller space for hovering/selecting/dragging on child blocks .editor-block-list__layout & { - left: -$block-side-ui-width; - right: -$block-side-ui-width; + left: 0; + right: 0; } // Full width blocks don't have the place to expand on the side @@ -81,10 +81,12 @@ // Allow Drag & Drop when clicking on the empty area of the mover and the settings menu -.editor-block-list__block .editor-block-mover, -.editor-block-list__block .editor-block-settings-menu { +.editor-block-list__layout .editor-block-list__block .editor-block-mover, +.editor-block-list__layout .editor-block-list__block .editor-block-settings-menu { pointer-events: none; + // Nested blocks don't have any side affordance for drag and drop + .editor-block-list__layout &, > * { pointer-events: auto; } @@ -127,8 +129,9 @@ @include break-small() { // The block mover needs to stay inside the block to allow clicks when hovering the block - padding-left: $block-padding + $block-side-ui-padding; - padding-right: $block-padding + $block-side-ui-padding; + // subtract 1px for border width + padding-left: $block-padding + $block-side-ui-padding - 1px; + padding-right: $block-padding + $block-side-ui-padding - 1px; } // Prevent collapsing margins @todo try and revisit this, it's conducive to theming to allow these to collapse @@ -377,47 +380,10 @@ 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 + // Wide and full-wide + &[data-align="wide"], &[data-align="full"] { - - // compensate for main container padding - @include break-small() { - margin-left: -$block-side-ui-padding; - margin-right: -$block-side-ui-padding; - } - - > .editor-block-list__block-edit { - margin-left: -$block-padding; - margin-right: -$block-padding; - - @include break-small() { - margin-left: -$block-side-ui-padding - $block-padding; - margin-right: -$block-side-ui-padding - $block-padding; - } - - // this explicitly sets the width of the block, to override the fit-content from the image block - figure { - width: 100%; - } - } - - > .editor-block-list__block-edit:before { - left: 0; - right: 0; - border-left-width: 0; - border-right-width: 0; - } - - // Mover and settings in full-wide + // Mover and settings above > .editor-block-mover, > .editor-block-settings-menu { top: -$block-side-ui-width - 1px; // move upwards the height of the button +1px for border @@ -469,6 +435,38 @@ } } + // Full-wide + &[data-align="full"] { + + // compensate for main container padding, subtract border + @include break-small() { + margin-left: -$block-side-ui-padding + 1px; + margin-right: -$block-side-ui-padding + 1px; + } + + > .editor-block-list__block-edit { + margin-left: -$block-padding; + margin-right: -$block-padding; + + @include break-small() { + margin-left: -$block-side-ui-padding - $block-padding; + margin-right: -$block-side-ui-padding - $block-padding; + } + + // this explicitly sets the width of the block, to override the fit-content from the image block + figure { + width: 100%; + } + } + + > .editor-block-list__block-edit:before { + left: 0; + right: 0; + border-left-width: 0; + border-right-width: 0; + } + } + // Clear floats &[data-clear="true"] { float: none; @@ -494,12 +492,9 @@ > .editor-block-mover { position: absolute; top: 0; - min-height: 50%; // stretch to fill half of the available space to increase hoverable area width: $block-side-ui-width + $block-side-ui-clearance; - - /* Necessary for drag indicator */ - cursor: move;/* Fallback for IE/Edge < 14 */ - cursor: grab; + height: 100%; // stretch to fill half of the available space to increase hoverable area + max-height: $block-side-ui-width * 4; // stretch to fill half of the available space to increase hoverable area } // Elevate when selected or hovered @@ -758,19 +753,19 @@ @include break-small() { // stack borders - margin-left: -$block-padding - $block-side-ui-padding - $block-parent-side-ui-clearance - 1px; - margin-right: -$block-padding - $block-side-ui-padding - $block-parent-side-ui-clearance - 1px; + margin-left: -$parent-block-padding - $block-side-ui-width - 1px; + margin-right: -$parent-block-padding - $block-side-ui-width - 1px; - // fixme nested + // position toolbar for nested .editor-block-list__block & { - margin-left: -$block-padding - $block-side-ui-padding - 1px; + margin-left: -$block-padding - $block-side-ui-width - 1px; margin-right: -$block-padding - $block-side-ui-padding - 1px; } // except for wide elements, this causes a horizontal scrollbar [data-align="full"] & { - margin-left: -$block-padding - $block-side-ui-padding; - margin-right: -$block-padding - $block-side-ui-padding; + margin-left: -$block-padding - $block-side-ui-width; + margin-right: -$block-padding - $block-side-ui-width; } } @@ -814,7 +809,7 @@ // Position in the top right of the border right: -$block-parent-side-ui-clearance - 1px; - top: -1px; + top: 0; // Nested .editor-block-list__block-edit & { @@ -825,14 +820,21 @@ padding: 0; border: none; background: transparent; - padding: 0px; line-height: 1; font-family: $default-font; font-size: 11px; - cursor: default; - background: rgba( $white, .8 ); - border: 1px solid $blue-medium-300; - padding: 2px 4px; + //cursor: default; + //background: rgba( $white, .8 ); + //border: 1px solid $blue-medium-300; + padding: 4px 4px; + background: $light-gray-200; + color: $dark-gray-500; + margin: 4px; + border-radius: 4px; + + // Drag indicator + cursor: move; /* Fallback for IE/Edge < 14 */ + cursor: grab; // Animate in .editor-block-list__block:hover & { diff --git a/editor/components/default-block-appender/style.scss b/editor/components/default-block-appender/style.scss index 66d14d99f5492b..8a20f01ec63c03 100644 --- a/editor/components/default-block-appender/style.scss +++ b/editor/components/default-block-appender/style.scss @@ -74,7 +74,7 @@ $empty-paragraph-height: $text-editor-font-size * 4; right: $item-spacing; // show on the right on mobile @include break-small { - left: -$parent-block-side-ui-padding; + left: -$icon-button-size - $block-side-ui-clearance - $block-parent-side-ui-clearance; right: auto; } diff --git a/editor/components/post-title/style.scss b/editor/components/post-title/style.scss index 95443c8d93c50e..c283887915a27e 100644 --- a/editor/components/post-title/style.scss +++ b/editor/components/post-title/style.scss @@ -22,15 +22,18 @@ font-weight: 600; } - &.is-selected .editor-post-title__input, - .editor-post-title__input:hover { + &.is-selected .editor-post-title__input { // use opacity to work in various editor styles - border: 1px solid $dark-opacity-light-500; + border-color: $light-opacity-light-500; .is-dark-theme & { border-color: $light-opacity-light-500; } } + + .editor-post-title__input:hover { + border-color: $blue-medium-300; + } } .editor-post-title .editor-post-permalink { From 696ce2f9f50c0f26d954c4ed12fe443a1db27f40 Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Wed, 30 May 2018 13:20:56 +0200 Subject: [PATCH 08/14] Fix the empty appender in more than columns block The empty appender, when on mobile, or in a nested block, shows a reduced version. Previously this was only in the columns block, now it's any block that uses nested children. --- core-blocks/columns/editor.scss | 15 --------------- editor/components/block-list/style.scss | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/core-blocks/columns/editor.scss b/core-blocks/columns/editor.scss index f23c87cb7dc138..d68749cccf9d21 100644 --- a/core-blocks/columns/editor.scss +++ b/core-blocks/columns/editor.scss @@ -37,18 +37,3 @@ margin-right: $block-side-ui-padding; } } - -// Hide appender shortcuts in columns -// @todo This essentially duplicates the mobile styles for the appender component -// It would be nice to be able to use element queries in that component instead https://github.com/tomhodgins/element-queries-spec -.wp-block-columns { - .editor-inserter-with-shortcuts { - display: none; - } - - .editor-block-list__empty-block-inserter, - .editor-default-block-appender .editor-inserter { - left: auto; - right: $item-spacing; - } -} diff --git a/editor/components/block-list/style.scss b/editor/components/block-list/style.scss index e875a64a04f1e6..1d209ef712e4d0 100644 --- a/editor/components/block-list/style.scss +++ b/editor/components/block-list/style.scss @@ -478,6 +478,21 @@ bottom: -3px; margin: 0 $block-padding; } + + // Hide appender shortcuts in nested blocks + // This essentially duplicates the mobile styles for the appender component + // It would be nice to be able to use element queries in that component instead https://github.com/tomhodgins/element-queries-spec + .editor-block-list__layout { + .editor-inserter-with-shortcuts { + display: none; + } + + .editor-block-list__empty-block-inserter, + .editor-default-block-appender .editor-inserter { + left: auto; + right: $item-spacing; + } + } } From feaa3f0b18a500ba55364c33fb3cccf401bb559e Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Wed, 30 May 2018 13:47:16 +0200 Subject: [PATCH 09/14] Tune hover label again. --- edit-post/assets/stylesheets/_colors.scss | 1 + editor/components/block-list/style.scss | 17 ++++++----------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/edit-post/assets/stylesheets/_colors.scss b/edit-post/assets/stylesheets/_colors.scss index 7a6ea91988e865..15f505c5de613f 100644 --- a/edit-post/assets/stylesheets/_colors.scss +++ b/edit-post/assets/stylesheets/_colors.scss @@ -80,6 +80,7 @@ $blue-medium-300: #66C6E4; $blue-medium-200: #BFE7F3; $blue-medium-100: #E5F5FA; $blue-medium-highlight: #b3e7fe; +$blue-medium-focus: #007cba; // Alert colors $alert-yellow: #f0b849; diff --git a/editor/components/block-list/style.scss b/editor/components/block-list/style.scss index 1d209ef712e4d0..bf7469c3d6f275 100644 --- a/editor/components/block-list/style.scss +++ b/editor/components/block-list/style.scss @@ -243,7 +243,7 @@ // Hover style &.is-hovered > .editor-block-list__block-edit:before { - outline: 1px solid $blue-medium-300; + outline: 1px solid $blue-medium-focus; } } @@ -823,12 +823,12 @@ z-index: z-index( '.editor-block-list__breadcrumb' ); // Position in the top right of the border - right: -$block-parent-side-ui-clearance - 1px; + right: -$block-parent-side-ui-clearance; top: 0; // Nested .editor-block-list__block-edit & { - right: $parent-block-padding - $block-padding - $block-parent-side-ui-clearance - 1px; + right: $parent-block-padding - $block-padding - $block-parent-side-ui-clearance; } .components-toolbar { @@ -838,15 +838,10 @@ line-height: 1; font-family: $default-font; font-size: 11px; - //cursor: default; - //background: rgba( $white, .8 ); - //border: 1px solid $blue-medium-300; padding: 4px 4px; - background: $light-gray-200; - color: $dark-gray-500; - margin: 4px; - border-radius: 4px; - + background: $blue-medium-focus; + color: $white; + // Drag indicator cursor: move; /* Fallback for IE/Edge < 14 */ cursor: grab; From 9bb97aaa41cfdd614d8cc5d5ca8633d0db3530ce Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Wed, 30 May 2018 14:11:21 +0200 Subject: [PATCH 10/14] Fix rebase issue. --- editor/components/post-title/style.scss | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/editor/components/post-title/style.scss b/editor/components/post-title/style.scss index c283887915a27e..1acac072b57e05 100644 --- a/editor/components/post-title/style.scss +++ b/editor/components/post-title/style.scss @@ -3,13 +3,13 @@ padding: 5px 0; @include break-small() { - padding: 5px $block-side-ui-padding; + padding: 5px $block-parent-side-ui-clearance; } .editor-post-title__input { display: block; width: 100%; - padding: #{ $block-padding + 5px } $block-padding; + padding: #{ $block-padding + 5px } $parent-block-padding; margin: 0; box-shadow: none; border: 1px solid transparent; @@ -24,7 +24,7 @@ &.is-selected .editor-post-title__input { // use opacity to work in various editor styles - border-color: $light-opacity-light-500; + border-color: $dark-opacity-light-500; .is-dark-theme & { border-color: $light-opacity-light-500; @@ -32,7 +32,7 @@ } .editor-post-title__input:hover { - border-color: $blue-medium-300; + border-color: $blue-medium-focus; } } @@ -45,7 +45,7 @@ right: 0; @include break-small() { - left: $block-side-ui-padding; - right: $block-side-ui-padding; + left: $block-parent-side-ui-clearance; + right: $block-parent-side-ui-clearance; } } From f527cf4712039ad7724e197289b7f7c630f5f78c Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 30 May 2018 13:54:18 +0100 Subject: [PATCH 11/14] hide outlines from empty default blocks --- editor/components/block-list/block.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/components/block-list/block.js b/editor/components/block-list/block.js index fa6fa18dea7246..70eb8f82088c9e 100644 --- a/editor/components/block-list/block.js +++ b/editor/components/block-list/block.js @@ -431,7 +431,7 @@ export class BlockListBlock extends Component { // 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 shouldShowBreadcrumb = isHovered && ! isEmptyDefaultBlock; const shouldShowContextualToolbar = ! showSideInserter && isSelected && ! isTypingWithinBlock && isValid && ( ! hasFixedToolbar || ! isLargeViewport ); const shouldShowMobileToolbar = shouldAppearSelected; const { error, dragging } = this.state; @@ -447,7 +447,7 @@ export class BlockListBlock extends Component { 'has-warning': ! isValid || !! error, 'is-selected': shouldAppearSelected, 'is-multi-selected': isMultiSelected, - 'is-hovered': isHovered, + 'is-hovered': isHovered && ! isEmptyDefaultBlock, 'is-shared': isSharedBlock( blockType ), 'is-hidden': dragging, 'is-typing': isTypingWithinBlock, From 8e12ea7c16dace4e03cc4d01d943954a1b62d7c1 Mon Sep 17 00:00:00 2001 From: jasmussen Date: Wed, 30 May 2018 16:34:04 +0200 Subject: [PATCH 12/14] Fix paddings and hover breadcrumb on classic block. --- core-blocks/freeform/editor.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core-blocks/freeform/editor.scss b/core-blocks/freeform/editor.scss index 091ee42dac7100..56bf9a7aa52583 100644 --- a/core-blocks/freeform/editor.scss +++ b/core-blocks/freeform/editor.scss @@ -127,7 +127,7 @@ } // Don't show block type label for classic block - &.is-hovered .editor-block-breadcrumb { + &.is-hovered .editor-block-list__breadcrumb { display: none; } } @@ -140,7 +140,7 @@ div[data-type="core/freeform"] .editor-block-contextual-toolbar + div { .freeform-toolbar { width: auto; - margin: -$block-padding; + margin: #{ -$block-padding } #{ -$parent-block-padding }; margin-bottom: $block-padding; position: sticky; z-index: z-index( '.freeform-toolbar' ); From 3bcec0f207ddd09dd33b449f82d41a8ce01fa874 Mon Sep 17 00:00:00 2001 From: jasmussen Date: Wed, 30 May 2018 16:38:15 +0200 Subject: [PATCH 13/14] Fade the title block border. --- editor/components/post-title/style.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/editor/components/post-title/style.scss b/editor/components/post-title/style.scss index 1acac072b57e05..6b16b72eb10e5c 100644 --- a/editor/components/post-title/style.scss +++ b/editor/components/post-title/style.scss @@ -16,6 +16,7 @@ background: transparent; font-family: $editor-font; line-height: $default-line-height; + transition: border .1s ease-out; // Match h1 heading font-size: 2.441em; From 29e17925d91514f2a99c8fc237e275e3ad638f08 Mon Sep 17 00:00:00 2001 From: Joen Asmussen Date: Fri, 1 Jun 2018 09:56:53 +0200 Subject: [PATCH 14/14] Address feedback. Add border to switcher component instead. Add comment to explain z index. --- editor/components/block-mover/style.scss | 1 + editor/components/block-switcher/style.scss | 3 +++ editor/components/block-toolbar/style.scss | 5 ----- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/editor/components/block-mover/style.scss b/editor/components/block-mover/style.scss index b467fe8f76793a..ddea50def9bfd2 100644 --- a/editor/components/block-mover/style.scss +++ b/editor/components/block-mover/style.scss @@ -56,6 +56,7 @@ &:hover, &:active, &:focus { + // Buttons are stacked with overlapping border to look like a unit, so elevate on interactions. z-index: z-index( '.editor-block-mover__control' ); } } diff --git a/editor/components/block-switcher/style.scss b/editor/components/block-switcher/style.scss index 8b268bbeeec02a..dc791a3a3322e3 100644 --- a/editor/components/block-switcher/style.scss +++ b/editor/components/block-switcher/style.scss @@ -12,6 +12,9 @@ padding: 8px; border-radius: 0; + // Add a right border to show as separator in the block toolbar. + border-right: 1px solid $light-gray-700; + &:focus:before { top: -3px; right: -3px; diff --git a/editor/components/block-toolbar/style.scss b/editor/components/block-toolbar/style.scss index 495f9690ad9eda..2a34b83327b758 100644 --- a/editor/components/block-toolbar/style.scss +++ b/editor/components/block-toolbar/style.scss @@ -15,11 +15,6 @@ border: none; } - // Only show the left border if the Switcher is present - .editor-block-switcher + div > .components-toolbar { - border-left: 1px solid $light-gray-700; - } - // this should probably have its own class > div { display: flex;