From add68b9e980bd6b48b3b2eef060d53e2afe205fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 9 Aug 2018 12:31:19 +0200 Subject: [PATCH 01/21] Debug: colors are fun! --- packages/editor/src/components/block-list/style.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/editor/src/components/block-list/style.scss b/packages/editor/src/components/block-list/style.scss index 31a991f0c4ef8..b54dc566c10e8 100644 --- a/packages/editor/src/components/block-list/style.scss +++ b/packages/editor/src/components/block-list/style.scss @@ -42,9 +42,11 @@ // Use opacity to work in various editor styles. background-color: $dark-opacity-light-200; + background-color: red; .is-dark-theme & { background-color: $light-opacity-light-200; + background-color: blue; } @include break-small { @@ -54,6 +56,7 @@ &.is-visible > .editor-block-list__block-draggable-inner { visibility: visible; + background-color: green; } @include break-small { From d4f6fa7faaaa7e267cb8ad259abd9cdb28f233af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 9 Aug 2018 12:36:14 +0200 Subject: [PATCH 02/21] Debug: make the draggable area visible --- packages/editor/src/components/block-list/style.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor/src/components/block-list/style.scss b/packages/editor/src/components/block-list/style.scss index b54dc566c10e8..0090aef67feae 100644 --- a/packages/editor/src/components/block-list/style.scss +++ b/packages/editor/src/components/block-list/style.scss @@ -38,7 +38,7 @@ right: 0; bottom: 0; left: 0; - visibility: hidden; + // visibility: hidden; // Use opacity to work in various editor styles. background-color: $dark-opacity-light-200; From d06670fcb2c18a9affd6dfc23f330990f03862eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 9 Aug 2018 12:32:01 +0200 Subject: [PATCH 03/21] We're going to get rid of side grabs So we don't need these. --- .../src/components/block-list/style.scss | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/packages/editor/src/components/block-list/style.scss b/packages/editor/src/components/block-list/style.scss index 0090aef67feae..14d9849a90022 100644 --- a/packages/editor/src/components/block-list/style.scss +++ b/packages/editor/src/components/block-list/style.scss @@ -48,10 +48,6 @@ background-color: $light-opacity-light-200; background-color: blue; } - - @include break-small { - margin: 0 48px; - } } &.is-visible > .editor-block-list__block-draggable-inner { @@ -59,25 +55,6 @@ background-color: green; } - @include break-small { - // 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: 0; - right: 0; - } - - // Full width blocks don't have the place to expand on the side - .editor-block-list__block[data-align="full"] & { - left: 0; - right: 0; - } - } - - cursor: move; // Fallback for IE/Edge < 14 cursor: grab; } From c119acb643d3c04181c994b5dfe1d59987c7acc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 9 Aug 2018 12:38:43 +0200 Subject: [PATCH 04/21] Match breadcrumb positioning --- packages/editor/src/components/block-list/style.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/editor/src/components/block-list/style.scss b/packages/editor/src/components/block-list/style.scss index 14d9849a90022..0ed94985b25e7 100644 --- a/packages/editor/src/components/block-list/style.scss +++ b/packages/editor/src/components/block-list/style.scss @@ -26,8 +26,8 @@ .editor-block-list__layout .editor-block-list__block-draggable { position: absolute; - top: 0; - right: 0; + top: -14px; // TODO: review what breadcrumb component uses + right: -15px; bottom: 0; left: 0; z-index: z-index(".editor-block-list__block-draggable"); From 32a465f5236baebc943270ac1151272b14a3020c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 9 Aug 2018 12:45:45 +0200 Subject: [PATCH 05/21] Position the handle in the top right corner, alongside the label --- .../editor/src/components/block-list/block-draggable.js | 8 +++++++- packages/editor/src/components/block-list/style.scss | 7 ------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/editor/src/components/block-list/block-draggable.js b/packages/editor/src/components/block-list/block-draggable.js index 67f77189b36bd..b528a62c2574b 100644 --- a/packages/editor/src/components/block-list/block-draggable.js +++ b/packages/editor/src/components/block-list/block-draggable.js @@ -23,7 +23,13 @@ function BlockDraggable( { rootClientId, index, clientId, layout, isDragging, .. return ( -
+ { + /* + * TODO: remove the DnD handle text. + * We use this to teach the browser to give the div some space. + */ + } +
DnD handle
); } diff --git a/packages/editor/src/components/block-list/style.scss b/packages/editor/src/components/block-list/style.scss index 0ed94985b25e7..d349db11785c6 100644 --- a/packages/editor/src/components/block-list/style.scss +++ b/packages/editor/src/components/block-list/style.scss @@ -28,16 +28,9 @@ position: absolute; top: -14px; // TODO: review what breadcrumb component uses right: -15px; - bottom: 0; - left: 0; z-index: z-index(".editor-block-list__block-draggable"); > .editor-block-list__block-draggable-inner { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; // visibility: hidden; // Use opacity to work in various editor styles. From 97f17ea6e7d2985cbdfcfaf935b927dbeda82619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 9 Aug 2018 12:52:16 +0200 Subject: [PATCH 06/21] Expose the handle, hide the contents --- edit-post/assets/stylesheets/_z-index.scss | 4 ++-- packages/editor/src/components/block-list/style.scss | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/edit-post/assets/stylesheets/_z-index.scss b/edit-post/assets/stylesheets/_z-index.scss index 9a350e6868e7f..6b21abbe1a494 100644 --- a/edit-post/assets/stylesheets/_z-index.scss +++ b/edit-post/assets/stylesheets/_z-index.scss @@ -34,8 +34,8 @@ $z-layers: ( // Active pill button ".components-button.is-button {:focus or .is-primary}": 1, - // Should have lower index than anything else positioned inside the block containers - ".editor-block-list__block-draggable": 0, + // The drag handle should show up above the entire UI + ".editor-block-list__block-draggable": 1000000000, // The draggable element should show up above the entire UI ".components-draggable__clone": 1000000000, diff --git a/packages/editor/src/components/block-list/style.scss b/packages/editor/src/components/block-list/style.scss index d349db11785c6..036778c172785 100644 --- a/packages/editor/src/components/block-list/style.scss +++ b/packages/editor/src/components/block-list/style.scss @@ -31,21 +31,21 @@ z-index: z-index(".editor-block-list__block-draggable"); > .editor-block-list__block-draggable-inner { - // visibility: hidden; + visibility: hidden; // Use opacity to work in various editor styles. background-color: $dark-opacity-light-200; - background-color: red; + // background-color: red; .is-dark-theme & { background-color: $light-opacity-light-200; - background-color: blue; + // background-color: blue; } } &.is-visible > .editor-block-list__block-draggable-inner { visibility: visible; - background-color: green; + // background-color: green; } cursor: move; // Fallback for IE/Edge < 14 From 9c694b66e630b7b998100c39faf6eb99936e7e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 9 Aug 2018 13:01:27 +0200 Subject: [PATCH 07/21] Dont make the handle ever visible. The drag handle no longer overlaps the block content div, so we can't render a placeholder in the handle itself. We need to figure somethingelse out. --- .../editor/src/components/block-list/style.scss | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/packages/editor/src/components/block-list/style.scss b/packages/editor/src/components/block-list/style.scss index 036778c172785..68e3386eb8256 100644 --- a/packages/editor/src/components/block-list/style.scss +++ b/packages/editor/src/components/block-list/style.scss @@ -32,20 +32,6 @@ > .editor-block-list__block-draggable-inner { visibility: hidden; - - // Use opacity to work in various editor styles. - background-color: $dark-opacity-light-200; - // background-color: red; - - .is-dark-theme & { - background-color: $light-opacity-light-200; - // background-color: blue; - } - } - - &.is-visible > .editor-block-list__block-draggable-inner { - visibility: visible; - // background-color: green; } cursor: move; // Fallback for IE/Edge < 14 From 123d37b8b5ef5745a267d43470ae1385c9148175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 9 Aug 2018 18:08:57 +0200 Subject: [PATCH 08/21] Add grab affordance --- packages/editor/src/components/block-list/breadcrumb.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/editor/src/components/block-list/breadcrumb.js b/packages/editor/src/components/block-list/breadcrumb.js index ca14b1d346c94..38bab6d23b579 100644 --- a/packages/editor/src/components/block-list/breadcrumb.js +++ b/packages/editor/src/components/block-list/breadcrumb.js @@ -53,6 +53,7 @@ export class BlockBreadcrumb extends Component { return (
+
:::  
{ rootClientId && ( From a37bcdeb990a1b4e1b6dfeffd008e2adc572da53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 10 Aug 2018 11:16:34 +0200 Subject: [PATCH 09/21] HACK: PoC to improve the draggable indicator This tweaks the dashicon viewBox to render a not too embarrasing draggable indicator. This needs fixing. --- packages/components/src/dashicon/index.js | 5 +++-- packages/editor/src/components/block-list/breadcrumb.js | 4 ++-- packages/editor/src/components/block-list/style.scss | 4 ++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/components/src/dashicon/index.js b/packages/components/src/dashicon/index.js index c103795736e63..4541f1dc56ecf 100644 --- a/packages/components/src/dashicon/index.js +++ b/packages/components/src/dashicon/index.js @@ -15,12 +15,13 @@ export default class Dashicon extends Component { return ( this.props.icon !== nextProps.icon || this.props.size !== nextProps.size || + this.props.viewBox !== nextProps.viewBox || this.props.className !== nextProps.className ); } render() { - const { icon, className, size = 20 } = this.props; + const { icon, className, size = 20, viewBox = 20 } = this.props; let path; switch ( icon ) { @@ -893,7 +894,7 @@ export default class Dashicon extends Component { xmlns="http://www.w3.org/2000/svg" width={ size } height={ size } - viewBox="0 0 20 20" + viewBox={ '0 0 ' + viewBox + ' ' + viewBox } // TODO: if we like this approach, remove this hack and implement upstream > diff --git a/packages/editor/src/components/block-list/breadcrumb.js b/packages/editor/src/components/block-list/breadcrumb.js index 38bab6d23b579..71b5798c8629e 100644 --- a/packages/editor/src/components/block-list/breadcrumb.js +++ b/packages/editor/src/components/block-list/breadcrumb.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { Component, Fragment } from '@wordpress/element'; -import { Toolbar } from '@wordpress/components'; +import { Dashicon, Toolbar } from '@wordpress/components'; import { withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; @@ -53,7 +53,7 @@ export class BlockBreadcrumb extends Component { return (
-
:::  
+
{ rootClientId && ( diff --git a/packages/editor/src/components/block-list/style.scss b/packages/editor/src/components/block-list/style.scss index 68e3386eb8256..0d90f098db7a0 100644 --- a/packages/editor/src/components/block-list/style.scss +++ b/packages/editor/src/components/block-list/style.scss @@ -965,6 +965,10 @@ .editor-block-list__block:hover & { @include fade_in(0.1s); } + + .editor-block-list__breadcrumb-drag-handle { + margin-right: 2px; + } } } From fcd43b791d2d37b31bbc6696b6f7979f416c4ad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Mon, 13 Aug 2018 17:54:20 +0200 Subject: [PATCH 10/21] Use opacity to communicate what block is being dragged. Previous to this refactor, it used to be a div inside the block wrapper that would become visible when the block was being dragged. That div would appear as grey. By refactoring the drag handler to the breadcrumb we no longer have that div, so we seek to use a different technique to communicate the same behavior. I also think is nicer to show the original content. --- packages/editor/src/components/block-list/style.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor/src/components/block-list/style.scss b/packages/editor/src/components/block-list/style.scss index 0d90f098db7a0..968794c00ffd9 100644 --- a/packages/editor/src/components/block-list/style.scss +++ b/packages/editor/src/components/block-list/style.scss @@ -54,7 +54,7 @@ .editor-block-list__block { &.is-hidden *, &.is-hidden > * { - visibility: hidden; + opacity: 0.8; } .editor-block-list__block-edit .reusable-block-edit-panel * { From ebfe05a0d407ac1d1024d12bbd8f623f29bb80c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 16 Aug 2018 18:49:42 +0200 Subject: [PATCH 11/21] Create withDraggable HOC --- .../src/higher-order/with-draggable/README.md | 80 +++++++++ .../src/higher-order/with-draggable/index.js | 154 ++++++++++++++++++ .../higher-order/with-draggable/style.scss | 20 +++ packages/components/src/index.js | 1 + 4 files changed, 255 insertions(+) create mode 100644 packages/components/src/higher-order/with-draggable/README.md create mode 100644 packages/components/src/higher-order/with-draggable/index.js create mode 100644 packages/components/src/higher-order/with-draggable/style.scss diff --git a/packages/components/src/higher-order/with-draggable/README.md b/packages/components/src/higher-order/with-draggable/README.md new file mode 100644 index 0000000000000..ebb07d65569ce --- /dev/null +++ b/packages/components/src/higher-order/with-draggable/README.md @@ -0,0 +1,80 @@ +# withDraggable + +`withDraggable` is a Higher-Order Component that provides a way to set up a cross-browser (including IE) customisable drag image, and the transfer data for the drag event. It decouples the drag handle and the element to drag: it wraps the component that will be the drag handle, and it should be provided the DOM ID of the element to drag. + +Note that the drag handle needs to declare the `draggable="true"` property. The `withDraggable` component only takes care of the logic to setup the drag image and the transfer data, but is not concerned with creating an actual DOM element that is draggable. + +## Props + +The component injects the following props into the wrapped component: + +### onDragStart + +A function that initializes the drag event, setting up the transfer data and creating the drag image. It returns a function to be called on the `dragstart` DOM event. + +- Type: `Function` +- Required: Yes +- Arguments: + - `elementId`: DOM id of the element to be dragged + - `data`: the [data](https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/dataTransfer) to be transfered by the event + +## Usage + +```jsx +import { Dashicon, Panel, PanelBody, withDraggable } from '@wordpress/components'; + +const MyDraggable = ( { onDragStart } ) => ( +
+ + + + + + +
+); + +export default withDraggable( MyDraggable ); +``` + +If the wrapped element would want to inject their own logic into the `dragstart` event, it should initialize the `onDragStart` prop provided by `withDraggable` in that event handler. For example: + +```jsx + +import { Dashicon, Panel, PanelBody, withDraggable } from '@wordpress/components'; + +const class MyDraggable extends Component { + + constructor() { + super( ...arguments ); + this.myDragStart = this.myDragStart.bind( this ); + } + + myDragStart( event ){ + this.props.onDragStart( 'draggable-panel', {} )( event ); + + // can do whatever is necessary after the event has been set up + } + + render( ) { + return ( +
+ + + + + +
+ ); + } +} + +export default withDraggable( MyDraggable ); +``` \ No newline at end of file diff --git a/packages/components/src/higher-order/with-draggable/index.js b/packages/components/src/higher-order/with-draggable/index.js new file mode 100644 index 0000000000000..5774c2887e048 --- /dev/null +++ b/packages/components/src/higher-order/with-draggable/index.js @@ -0,0 +1,154 @@ +/** + * WordPress Dependencies + */ +import { Component } from '@wordpress/element'; +import { createHigherOrderComponent } from '@wordpress/compose'; + +const dragImageClass = 'components-draggable__invisible-drag-image'; +const cloneWrapperClass = 'components-draggable__clone'; +const cloneHeightTransformationBreakpoint = 700; +const clonePadding = 20; + +const withDraggable = createHigherOrderComponent( + ( OriginalComponent ) => { + return class extends Component { + constructor() { + super( ...arguments ); + this.onDragStart = this.onDragStart.bind( this ); + this.onDragOver = this.onDragOver.bind( this ); + this.onDragEnd = this.onDragEnd.bind( this ); + this.resetDragState = this.resetDragState.bind( this ); + } + + componentWillUnmount() { + this.resetDragState(); + } + + /** + * Function that creates the dragstart event handler. + * + * @param {string} elementId The HTML id of the element to be dragged. + * @param {Object} data The data to be set to the event's dataTransfer - to be accessible in any later drop logic. + * @return {function} A function for wrapped components to use as their onDragStart handler. + */ + onDragStart( elementId, data ) { + return ( event ) => { + const element = document.getElementById( elementId ); + if ( ! element || ! data ) { + event.preventDefault(); + return; + } + + event.dataTransfer.setData( 'text', JSON.stringify( data ) ); + + // Set a fake drag image to avoid browser defaults. Remove from DOM + // right after. event.dataTransfer.setDragImage is not supported yet in + // IE, we need to check for its existence first. + if ( 'function' === typeof event.dataTransfer.setDragImage ) { + const dragImage = document.createElement( 'div' ); + dragImage.id = `drag-image-${ elementId }`; + dragImage.classList.add( dragImageClass ); + document.body.appendChild( dragImage ); + event.dataTransfer.setDragImage( dragImage, 0, 0 ); + setTimeout( () => { + document.body.removeChild( dragImage ); + } ); + } + + // Prepare element clone and append to element wrapper. + const elementRect = element.getBoundingClientRect(); + const elementWrapper = element.parentNode; + const elementTopOffset = parseInt( elementRect.top, 10 ); + const elementLeftOffset = parseInt( elementRect.left, 10 ); + const clone = element.cloneNode( true ); + clone.id = `clone-${ elementId }`; + this.cloneWrapper = document.createElement( 'div' ); + this.cloneWrapper.classList.add( cloneWrapperClass ); + this.cloneWrapper.style.width = `${ elementRect.width + ( clonePadding * 2 ) }px`; + + if ( elementRect.height > cloneHeightTransformationBreakpoint ) { + // Scale down clone if original element is larger than 700px. + this.cloneWrapper.style.transform = 'scale(0.5)'; + this.cloneWrapper.style.transformOrigin = 'top left'; + // Position clone near the cursor. + this.cloneWrapper.style.top = `${ event.clientY - 100 }px`; + this.cloneWrapper.style.left = `${ event.clientX }px`; + } else { + // Position clone right over the original element (20px padding). + this.cloneWrapper.style.top = `${ elementTopOffset - clonePadding }px`; + this.cloneWrapper.style.left = `${ elementLeftOffset - clonePadding }px`; + } + + // Hack: Remove iFrames as it's causing the embeds drag clone to freeze + [ ...clone.querySelectorAll( 'iframe' ) ].forEach( ( child ) => child.parentNode.removeChild( child ) ); + + this.cloneWrapper.appendChild( clone ); + elementWrapper.appendChild( this.cloneWrapper ); + + // Mark the current cursor coordinates. + this.cursorLeft = event.clientX; + this.cursorTop = event.clientY; + // Update cursor to 'grabbing', document wide. + document.body.classList.add( 'is-dragging-components-draggable' ); + + // connect listeners + document.addEventListener( 'dragover', this.onDragOver ); + document.addEventListener( 'dragend', this.onDragEnd ); + }; + } + + /** + * Updates positioning of element clone based on mouse movement during dragging. + * @param {Object} event The non-custom DragEvent. + */ + onDragOver( event ) { + this.cloneWrapper.style.top = + `${ parseInt( this.cloneWrapper.style.top, 10 ) + event.clientY - this.cursorTop }px`; + this.cloneWrapper.style.left = + `${ parseInt( this.cloneWrapper.style.left, 10 ) + event.clientX - this.cursorLeft }px`; + + // Update cursor coordinates. + this.cursorLeft = event.clientX; + this.cursorTop = event.clientY; + } + + /** + * Removes the element clone, resets cursor, and removes drag listener. + */ + onDragEnd( ) { + this.resetDragState(); + } + + /** + * Cleans up drag state when drag has completed, or component unmounts + * while dragging. + */ + resetDragState() { + // Remove listeners + document.removeEventListener( 'dragover', this.onDragOver ); + document.removeEventListener( 'dragend', this.onDragEnd ); + + // Remove drag clone + if ( this.cloneWrapper && this.cloneWrapper.parentNode ) { + this.cloneWrapper.parentNode.removeChild( this.cloneWrapper ); + this.cloneWrapper = null; + } + + // Reset cursor. + document.body.classList.remove( 'is-dragging-components-draggable' ); + } + + render() { + return ( + + ); + } + }; + }, + 'withDraggable' +); + +export default withDraggable; diff --git a/packages/components/src/higher-order/with-draggable/style.scss b/packages/components/src/higher-order/with-draggable/style.scss new file mode 100644 index 0000000000000..ad046f4e092a3 --- /dev/null +++ b/packages/components/src/higher-order/with-draggable/style.scss @@ -0,0 +1,20 @@ +body.is-dragging-components-draggable { + cursor: move;/* Fallback for IE/Edge < 14 */ + cursor: grabbing !important; +} + +.components-draggable__invisible-drag-image { + position: fixed; + left: -1000px; + height: 50px; + width: 50px; +} + +.components-draggable__clone { + position: fixed; + padding: 20px; + background: transparent; + pointer-events: none; + z-index: z-index(".components-draggable__clone"); + opacity: 0.8; +} diff --git a/packages/components/src/index.js b/packages/components/src/index.js index 182cb6e111c0d..402e220828286 100644 --- a/packages/components/src/index.js +++ b/packages/components/src/index.js @@ -62,6 +62,7 @@ export { default as navigateRegions } from './higher-order/navigate-regions'; export { default as withAPIData } from './higher-order/with-api-data'; export { default as withContext } from './higher-order/with-context'; export { default as withConstrainedTabbing } from './higher-order/with-constrained-tabbing'; +export { default as withDraggable } from './higher-order/with-draggable'; export { default as withFallbackStyles } from './higher-order/with-fallback-styles'; export { default as withFilters } from './higher-order/with-filters'; export { default as withFocusOutside } from './higher-order/with-focus-outside'; From ca3dbf69f150d867d3a32af0b4a604949cd94628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 16 Aug 2018 18:51:44 +0200 Subject: [PATCH 12/21] Refactor breadcrumb to use withDraggable HOC --- edit-post/assets/stylesheets/_z-index.scss | 2 +- .../editor/src/components/block-list/block.js | 24 ++++++++----------- .../src/components/block-list/breadcrumb.js | 8 +++---- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/edit-post/assets/stylesheets/_z-index.scss b/edit-post/assets/stylesheets/_z-index.scss index 6b21abbe1a494..0689fc5387e26 100644 --- a/edit-post/assets/stylesheets/_z-index.scss +++ b/edit-post/assets/stylesheets/_z-index.scss @@ -9,7 +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-block-list__breadcrumb": 1000000000, ".components-form-toggle__input": 1, ".editor-inserter__tabs": 1, ".editor-inserter__tab.is-active": 1, diff --git a/packages/editor/src/components/block-list/block.js b/packages/editor/src/components/block-list/block.js index 4d32a8069dc12..134ca861732e6 100644 --- a/packages/editor/src/components/block-list/block.js +++ b/packages/editor/src/components/block-list/block.js @@ -44,7 +44,6 @@ import BlockContextualToolbar from './block-contextual-toolbar'; import BlockMultiControls from './multi-controls'; import BlockMobileToolbar from './block-mobile-toolbar'; import BlockInsertionPoint from './insertion-point'; -import BlockDraggable from './block-draggable'; import IgnoreNestedEvents from './ignore-nested-events'; import InserterWithShortcuts from '../inserter-with-shortcuts'; import Inserter from '../inserter'; @@ -394,7 +393,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 && ! isPartOfMultiSelection && ! isTypingWithinBlock; const shouldRenderBlockSettings = ( isSelected || hoverArea === 'right' ) && ! isMultiSelecting && ! isPartOfMultiSelection; - const shouldShowBreadcrumb = isHovered && ! isEmptyDefaultBlock; + const shouldShowBreadcrumb = ( isSelected || isHovered ) && ! isEmptyDefaultBlock; const shouldShowContextualToolbar = ! showSideInserter && ( ( isSelected && ! isTypingWithinBlock && isValid ) || isFirstMultiSelected ) && ( ! hasFixedToolbar || ! isLargeViewport ); const shouldShowMobileToolbar = shouldAppearSelected; const { error, dragging } = this.state; @@ -481,18 +480,6 @@ export class BlockListBlock extends Component { ] } { ...wrapperProps } > - { ! isPartOfMultiSelection && isMovable && ( - - ) } { shouldShowInsertionPoint && ( ) } diff --git a/packages/editor/src/components/block-list/breadcrumb.js b/packages/editor/src/components/block-list/breadcrumb.js index 71b5798c8629e..e7c7c9aa760e9 100644 --- a/packages/editor/src/components/block-list/breadcrumb.js +++ b/packages/editor/src/components/block-list/breadcrumb.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { Component, Fragment } from '@wordpress/element'; -import { Dashicon, Toolbar } from '@wordpress/components'; +import { Dashicon, Toolbar, withDraggable } from '@wordpress/components'; import { withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; @@ -48,10 +48,10 @@ export class BlockBreadcrumb extends Component { } render() { - const { clientId, rootClientId } = this.props; + const { isDraggable, clientId, rootClientId, draggableData, draggableElementId, onDragStart } = this.props; return ( -
+
{ rootClientId && ( @@ -71,9 +71,9 @@ export default compose( [ withSelect( ( select, ownProps ) => { const { getBlockRootClientId } = select( 'core/editor' ); const { clientId } = ownProps; - return { rootClientId: getBlockRootClientId( clientId ), }; } ), + withDraggable, ] )( BlockBreadcrumb ); From 4cea178cbf36d2fab9ff949c41eb080e723bae16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 16 Aug 2018 18:59:38 +0200 Subject: [PATCH 13/21] Deprecate wp.components.Draggable in favor of wp.components.withDraggable --- docs/reference/deprecated.md | 1 + packages/components/src/draggable/index.js | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/docs/reference/deprecated.md b/docs/reference/deprecated.md index 0f8b1dabe43fc..ab28388a728e5 100644 --- a/docs/reference/deprecated.md +++ b/docs/reference/deprecated.md @@ -16,6 +16,7 @@ Gutenberg's deprecation policy is intended to support backwards-compatibility fo ## 3.6.0 + - `wp.components.Draggable` has been deprecated. Please, use `wp.components.withDraggable` instead. - `wp.editor.editorMediaUpload` has been removed. Please use `wp.editor.mediaUpload` instead. - `wp.utils.getMimeTypesArray` has been removed. - `wp.utils.mediaUpload` has been removed. Please use `wp.editor.mediaUpload` instead. diff --git a/packages/components/src/draggable/index.js b/packages/components/src/draggable/index.js index f6c85d6d40834..c909769d1a2e8 100644 --- a/packages/components/src/draggable/index.js +++ b/packages/components/src/draggable/index.js @@ -9,6 +9,7 @@ import classnames from 'classnames'; */ import { Component } from '@wordpress/element'; import { withSafeTimeout } from '@wordpress/compose'; +import deprecated from '@wordpress/deprecated'; const dragImageClass = 'components-draggable__invisible-drag-image'; const cloneWrapperClass = 'components-draggable__clone'; @@ -19,6 +20,11 @@ class Draggable extends Component { constructor() { super( ...arguments ); + deprecated( 'wp.components.Draggable', { + version: 3.6, + alternative: 'wp.components.withDraggable', + } ); + this.onDragStart = this.onDragStart.bind( this ); this.onDragOver = this.onDragOver.bind( this ); this.onDragEnd = this.onDragEnd.bind( this ); From 47f02fe17d8b73a4c89b7f3f525fe23e5eadb6dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 16 Aug 2018 19:17:32 +0200 Subject: [PATCH 14/21] fixup docs --- packages/components/src/higher-order/with-draggable/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/components/src/higher-order/with-draggable/README.md b/packages/components/src/higher-order/with-draggable/README.md index ebb07d65569ce..822881cd9c8df 100644 --- a/packages/components/src/higher-order/with-draggable/README.md +++ b/packages/components/src/higher-order/with-draggable/README.md @@ -31,7 +31,6 @@ const MyDraggable = ( { onDragStart } ) => ( icon="move" draggable="true" onDragStart={ onDragStart( "draggable-panel", {} ) } /> -
From 74d1b9c38013817e4786864659390960d080716e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 17 Aug 2018 12:16:53 +0200 Subject: [PATCH 15/21] Remove block-draggable it's only used internally by the block-list component. --- edit-post/assets/stylesheets/_z-index.scss | 5 +-- .../components/block-list/block-draggable.js | 37 ------------------- .../src/components/block-list/style.scss | 36 ------------------ 3 files changed, 1 insertion(+), 77 deletions(-) delete mode 100644 packages/editor/src/components/block-list/block-draggable.js diff --git a/edit-post/assets/stylesheets/_z-index.scss b/edit-post/assets/stylesheets/_z-index.scss index 0689fc5387e26..f9b48d93cdf42 100644 --- a/edit-post/assets/stylesheets/_z-index.scss +++ b/edit-post/assets/stylesheets/_z-index.scss @@ -34,10 +34,7 @@ $z-layers: ( // Active pill button ".components-button.is-button {:focus or .is-primary}": 1, - // The drag handle should show up above the entire UI - ".editor-block-list__block-draggable": 1000000000, - - // The draggable element should show up above the entire UI + // The drag image should show up above the entire UI ".components-draggable__clone": 1000000000, // Should have higher index than the inset/underlay used for dragging diff --git a/packages/editor/src/components/block-list/block-draggable.js b/packages/editor/src/components/block-list/block-draggable.js deleted file mode 100644 index b528a62c2574b..0000000000000 --- a/packages/editor/src/components/block-list/block-draggable.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - -/** - * WordPress dependencies - */ -import { Draggable } from '@wordpress/components'; - -function BlockDraggable( { rootClientId, index, clientId, layout, isDragging, ...props } ) { - const className = classnames( 'editor-block-list__block-draggable', { - 'is-visible': isDragging, - } ); - - const transferData = { - type: 'block', - fromIndex: index, - rootClientId, - clientId, - layout, - }; - - return ( - - { - /* - * TODO: remove the DnD handle text. - * We use this to teach the browser to give the div some space. - */ - } -
DnD handle
-
- ); -} - -export default BlockDraggable; diff --git a/packages/editor/src/components/block-list/style.scss b/packages/editor/src/components/block-list/style.scss index 968794c00ffd9..52717fb5a71ef 100644 --- a/packages/editor/src/components/block-list/style.scss +++ b/packages/editor/src/components/block-list/style.scss @@ -1,19 +1,4 @@ .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: -$block-parent-side-ui-clearance - $border-width; - right: -$block-parent-side-ui-clearance - $border-width; - - .editor-block-list__layout & { - left: -$border-width; - right: -$border-width; - } - } - } - // Hide the Block UI when dragging the block // This ensures the page scroll properly (no sticky elements) .editor-block-contextual-toolbar, @@ -24,21 +9,6 @@ } } -.editor-block-list__layout .editor-block-list__block-draggable { - position: absolute; - top: -14px; // TODO: review what breadcrumb component uses - right: -15px; - z-index: z-index(".editor-block-list__block-draggable"); - - > .editor-block-list__block-draggable-inner { - visibility: hidden; - } - - cursor: move; // Fallback for IE/Edge < 14 - cursor: grab; -} - - // Allow Drag & Drop when clicking on the empty area of the mover and the 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 { @@ -382,12 +352,6 @@ float: left; } - // There is no side UI clearance on full-wide 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: -$border-width; From 77f7ef1dee1588b053ed1e33e85f9621e3b61081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 17 Aug 2018 12:25:40 +0200 Subject: [PATCH 16/21] Add comment to z-index value --- edit-post/assets/stylesheets/_z-index.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edit-post/assets/stylesheets/_z-index.scss b/edit-post/assets/stylesheets/_z-index.scss index f9b48d93cdf42..2e98d2393e646 100644 --- a/edit-post/assets/stylesheets/_z-index.scss +++ b/edit-post/assets/stylesheets/_z-index.scss @@ -9,7 +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": 1000000000, + ".editor-block-list__breadcrumb": 1000000000, // used as a drag handler, we want it to be shown above the entire UI ".components-form-toggle__input": 1, ".editor-inserter__tabs": 1, ".editor-inserter__tab.is-active": 1, From 26ca9bfde22f030e5db9141f14943484cc1be5b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Mon, 20 Aug 2018 13:42:11 +0200 Subject: [PATCH 17/21] Make cursor affordance visible --- packages/editor/src/components/block-list/style.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/editor/src/components/block-list/style.scss b/packages/editor/src/components/block-list/style.scss index 52717fb5a71ef..63765e5f8123e 100644 --- a/packages/editor/src/components/block-list/style.scss +++ b/packages/editor/src/components/block-list/style.scss @@ -934,6 +934,9 @@ margin-right: 2px; } } + + cursor: move;/* Fallback for IE/Edge < 14 */ + cursor: grab; } .editor-block-list__descendant-arrow::before { From ac43bb39fca4c6f2d8e3dec5de34f4a115d32f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Mon, 20 Aug 2018 14:12:21 +0200 Subject: [PATCH 18/21] withDraggable injects initDragging instead of onDragStart The new name clarifies the purpose and allows the original component to have passed the onDragStart property by some parent component. --- .../src/higher-order/with-draggable/README.md | 10 +++++----- .../src/higher-order/with-draggable/index.js | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/components/src/higher-order/with-draggable/README.md b/packages/components/src/higher-order/with-draggable/README.md index 822881cd9c8df..4b12a4afca90a 100644 --- a/packages/components/src/higher-order/with-draggable/README.md +++ b/packages/components/src/higher-order/with-draggable/README.md @@ -8,7 +8,7 @@ Note that the drag handle needs to declare the `draggable="true"` property. The The component injects the following props into the wrapped component: -### onDragStart +### initDragging A function that initializes the drag event, setting up the transfer data and creating the drag image. It returns a function to be called on the `dragstart` DOM event. @@ -23,14 +23,14 @@ A function that initializes the drag event, setting up the transfer data and cre ```jsx import { Dashicon, Panel, PanelBody, withDraggable } from '@wordpress/components'; -const MyDraggable = ( { onDragStart } ) => ( +const MyDraggable = ( { initDragging } ) => (
+ onDragStart={ initDragging( "draggable-panel", {} ) } />
@@ -39,7 +39,7 @@ const MyDraggable = ( { onDragStart } ) => ( export default withDraggable( MyDraggable ); ``` -If the wrapped element would want to inject their own logic into the `dragstart` event, it should initialize the `onDragStart` prop provided by `withDraggable` in that event handler. For example: +If the wrapped element would want to inject their own logic into the `dragstart` event, it should initialize the `initDragging` prop provided by `withDraggable` in that event handler. For example: ```jsx @@ -53,7 +53,7 @@ const class MyDraggable extends Component { } myDragStart( event ){ - this.props.onDragStart( 'draggable-panel', {} )( event ); + this.props.initDragging( 'draggable-panel', {} )( event ); // can do whatever is necessary after the event has been set up } diff --git a/packages/components/src/higher-order/with-draggable/index.js b/packages/components/src/higher-order/with-draggable/index.js index 5774c2887e048..16ab27997d553 100644 --- a/packages/components/src/higher-order/with-draggable/index.js +++ b/packages/components/src/higher-order/with-draggable/index.js @@ -141,7 +141,7 @@ const withDraggable = createHigherOrderComponent( render() { return ( ); From 7c37b060a3848db00f1c5d70f5b13363526b4642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Mon, 20 Aug 2018 14:14:39 +0200 Subject: [PATCH 19/21] Breadcrumb notifies parent on drag start and end --- .../editor/src/components/block-list/block.js | 2 ++ .../src/components/block-list/breadcrumb.js | 20 +++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/editor/src/components/block-list/block.js b/packages/editor/src/components/block-list/block.js index 134ca861732e6..91fd06c5611b4 100644 --- a/packages/editor/src/components/block-list/block.js +++ b/packages/editor/src/components/block-list/block.js @@ -524,6 +524,8 @@ export class BlockListBlock extends Component { draggableElementId={ blockElementId } isDraggable={ ! isPartOfMultiSelection && isMovable } isHidden={ ! ( isHovered || isSelected ) || hoverArea !== 'left' } + onDragStart={ this.onDragStart } + onDragEnd={ this.onDragEnd } /> ) } { shouldShowContextualToolbar && } diff --git a/packages/editor/src/components/block-list/breadcrumb.js b/packages/editor/src/components/block-list/breadcrumb.js index e7c7c9aa760e9..cb182c36e5c53 100644 --- a/packages/editor/src/components/block-list/breadcrumb.js +++ b/packages/editor/src/components/block-list/breadcrumb.js @@ -28,6 +28,8 @@ export class BlockBreadcrumb extends Component { }; this.onFocus = this.onFocus.bind( this ); this.onBlur = this.onBlur.bind( this ); + this.onDragStart = this.onDragStart.bind( this ); + this.onDragEnd = this.onDragEnd.bind( this ); } onFocus( event ) { @@ -47,11 +49,25 @@ export class BlockBreadcrumb extends Component { } ); } + onDragStart( event ) { + const { draggableData, draggableElementId, initDragging, onDragStart } = this.props; + initDragging( draggableElementId, draggableData )( event ); + onDragStart( event ); + } + + onDragEnd( event ) { + this.props.onDragEnd( event ); + } + render() { - const { isDraggable, clientId, rootClientId, draggableData, draggableElementId, onDragStart } = this.props; + const { isDraggable, clientId, rootClientId } = this.props; return ( -
+
{ rootClientId && ( From 9d4793a1121dbfbaeef1dd606e67b2fac3b35097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Mon, 20 Aug 2018 14:18:30 +0200 Subject: [PATCH 20/21] Move deprecations to 3.7 version --- docs/reference/deprecated.md | 2 +- packages/components/src/draggable/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/deprecated.md b/docs/reference/deprecated.md index ab28388a728e5..115161f0762c7 100644 --- a/docs/reference/deprecated.md +++ b/docs/reference/deprecated.md @@ -7,6 +7,7 @@ Gutenberg's deprecation policy is intended to support backwards-compatibility fo ## 3.7.0 + - `wp.components.Draggable` has been deprecated. Please, use `wp.components.withDraggable` instead. - `wp.components.withAPIData` has been removed. Please use the Core Data module or `wp.apiFetch` directly instead. - `wp.data.dispatch("core").receiveTerms` has been deprecated. Please use `wp.data.dispatch("core").receiveEntityRecords` instead. - `getCategories` resolvers has been deprecated. Please use `getEntityRecords` resolver instead. @@ -16,7 +17,6 @@ Gutenberg's deprecation policy is intended to support backwards-compatibility fo ## 3.6.0 - - `wp.components.Draggable` has been deprecated. Please, use `wp.components.withDraggable` instead. - `wp.editor.editorMediaUpload` has been removed. Please use `wp.editor.mediaUpload` instead. - `wp.utils.getMimeTypesArray` has been removed. - `wp.utils.mediaUpload` has been removed. Please use `wp.editor.mediaUpload` instead. diff --git a/packages/components/src/draggable/index.js b/packages/components/src/draggable/index.js index c909769d1a2e8..63e2e50b5bc17 100644 --- a/packages/components/src/draggable/index.js +++ b/packages/components/src/draggable/index.js @@ -21,7 +21,7 @@ class Draggable extends Component { super( ...arguments ); deprecated( 'wp.components.Draggable', { - version: 3.6, + version: 3.7, alternative: 'wp.components.withDraggable', } ); From 9999a4fc743db6213baaafc26fba78785e1e5c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Mon, 20 Aug 2018 18:37:31 +0200 Subject: [PATCH 21/21] The breadcrumb should not be shown above overlays --- edit-post/assets/stylesheets/_z-index.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edit-post/assets/stylesheets/_z-index.scss b/edit-post/assets/stylesheets/_z-index.scss index 2e98d2393e646..c560caf2bfc97 100644 --- a/edit-post/assets/stylesheets/_z-index.scss +++ b/edit-post/assets/stylesheets/_z-index.scss @@ -9,7 +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": 1000000000, // used as a drag handler, we want it to be shown above the entire UI + ".editor-block-list__breadcrumb": 100, // drag handler, to be shown below any overlay ".components-form-toggle__input": 1, ".editor-inserter__tabs": 1, ".editor-inserter__tab.is-active": 1,