Skip to content

Commit

Permalink
Refactor dropzone for unmodified default blocks with `useBlockDropZon…
Browse files Browse the repository at this point in the history
…e` and `InsertionPoint` (#44647)

* Try integrating block-popover-drop-zone with insertion-point

* Fix changelog

* Fix animation and add e2e tests

* Remove fake html draggable once the drag starts

* Address minor reviews

* Add back deleted tests

* Merge getNearestBlockIndex and getDropTargetIndexAndOperation

* Add comment for insertion point
  • Loading branch information
kevin940726 committed Oct 13, 2022
1 parent fc081cc commit 96e5dc7
Show file tree
Hide file tree
Showing 24 changed files with 1,053 additions and 403 deletions.
7 changes: 6 additions & 1 deletion docs/reference-guides/data/data-core-block-editor.md
Expand Up @@ -1510,12 +1510,17 @@ _Parameters_

- _rootClientId_ `?string`: Optional root client ID of block list on which to insert.
- _index_ `?number`: Index at which block should be inserted.
- _\_\_unstableOptions_ `Object`: Whether or not to show an inserter button.
- _\_\_unstableOptions_ `?Object`: Additional options.

_Returns_

- `Object`: Action object.

_Properties_

- _\_\_unstableWithInserter_ `boolean`: Whether or not to show an inserter button.
- _operation_ `WPDropOperation`: The operation to perform when applied, either 'insert' or 'replace' for now.

### startDraggingBlocks

Returns an action object used in signalling that the user has begun to drag blocks.
Expand Down
4 changes: 4 additions & 0 deletions packages/block-editor/CHANGELOG.md
Expand Up @@ -7,6 +7,10 @@
- `FontSizePicker`: Update fluid utils so that only string, floats and integers are treated as valid font sizes for the purposes of fluid typography ([#44847](https://github.com/WordPress/gutenberg/pull/44847))
- `getTypographyClassesAndStyles()`: Ensure that font sizes are transformed into fluid values if fluid typography is activated ([#44852](https://github.com/WordPress/gutenberg/pull/44852))

### New features

- You can now drop files/blocks/HTML on unmodified default blocks to transform them into corresponding blocks ([#44647](https://github.com/WordPress/gutenberg/pull/44647)).

## 10.2.0 (2022-10-05)

## 10.1.0 (2022-09-21)
Expand Down
63 changes: 63 additions & 0 deletions packages/block-editor/src/components/block-popover/drop-zone.js
@@ -0,0 +1,63 @@
/**
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';
import { useReducedMotion } from '@wordpress/compose';
import { __unstableMotion as motion } from '@wordpress/components';

/**
* Internal dependencies
*/
import { store as blockEditorStore } from '../../store';
import BlockPopover from './index';

const animateVariants = {
hide: { opacity: 0, scaleY: 0.75 },
show: { opacity: 1, scaleY: 1 },
exit: { opacity: 0, scaleY: 0.9 },
};

function BlockDropZonePopover( {
__unstablePopoverSlot,
__unstableContentRef,
} ) {
const { clientId } = useSelect( ( select ) => {
const { getBlockOrder, getBlockInsertionPoint } =
select( blockEditorStore );
const insertionPoint = getBlockInsertionPoint();
const order = getBlockOrder( insertionPoint.rootClientId );

if ( ! order.length ) {
return {};
}

return {
clientId: order[ insertionPoint.index ],
};
}, [] );
const reducedMotion = useReducedMotion();

return (
<BlockPopover
clientId={ clientId }
__unstableCoverTarget
__unstablePopoverSlot={ __unstablePopoverSlot }
__unstableContentRef={ __unstableContentRef }
className="block-editor-block-popover__drop-zone"
>
<motion.div
data-testid="block-popover-drop-zone"
initial={
reducedMotion ? animateVariants.show : animateVariants.hide
}
animate={ animateVariants.show }
exit={
reducedMotion ? animateVariants.show : animateVariants.exit
}
className="block-editor-block-popover__drop-zone-foreground"
/>
</BlockPopover>
);
}

export default BlockDropZonePopover;
18 changes: 17 additions & 1 deletion packages/block-editor/src/components/block-popover/style.scss
Expand Up @@ -21,7 +21,7 @@
}

// Enable pointer events for the toolbar's content.
&:not(.block-editor-block-popover__inbetween) .components-popover__content {
&:not(.block-editor-block-popover__inbetween, .block-editor-block-popover__drop-zone) .components-popover__content {
* {
pointer-events: all;
}
Expand All @@ -48,3 +48,19 @@
}
}
}


.components-popover.block-editor-block-popover__drop-zone {
// Disable pointer events for dragging and dropping.
// This drop zone is fully presentational, the actual DnD implementation is handled elsewhere.
* {
pointer-events: none;
}

.block-editor-block-popover__drop-zone-foreground {
position: absolute;
inset: 0;
background-color: var(--wp-admin-theme-color);
border-radius: 2px;
}
}
Expand Up @@ -17,10 +17,11 @@ import { useReducedMotion } from '@wordpress/compose';
import Inserter from '../inserter';
import { store as blockEditorStore } from '../../store';
import BlockPopoverInbetween from '../block-popover/inbetween';
import BlockDropZonePopover from '../block-popover/drop-zone';

export const InsertionPointOpenRef = createContext();

function InsertionPointPopover( {
function InbetweenInsertionPointPopover( {
__unstablePopoverSlot,
__unstableContentRef,
} ) {
Expand Down Expand Up @@ -232,9 +233,30 @@ function InsertionPointPopover( {
}

export default function InsertionPoint( props ) {
const isVisible = useSelect( ( select ) => {
return select( blockEditorStore ).isBlockInsertionPointVisible();
const { insertionPoint, isVisible } = useSelect( ( select ) => {
const { getBlockInsertionPoint, isBlockInsertionPointVisible } =
select( blockEditorStore );
return {
insertionPoint: getBlockInsertionPoint(),
isVisible: isBlockInsertionPointVisible(),
};
}, [] );

return isVisible && <InsertionPointPopover { ...props } />;
if ( ! isVisible ) {
return null;
}

/**
* Render a popover that overlays the block when the desired operation is to replace it.
* Otherwise, render a popover in between blocks for the indication of inserting between them.
*/
return insertionPoint.operation === 'replace' ? (
<BlockDropZonePopover
// Force remount to trigger the animation.
key={ `${ insertionPoint.rootClientId }-${ insertionPoint.index }` }
{ ...props }
/>
) : (
<InbetweenInsertionPointPopover { ...props } />
);
}
1 change: 0 additions & 1 deletion packages/block-editor/src/components/index.js
Expand Up @@ -155,7 +155,6 @@ export {
export { default as __experimentalBlockPatternsList } from './block-patterns-list';
export { default as __experimentalPublishDateTimePicker } from './publish-date-time-picker';
export { default as __experimentalInspectorPopoverHeader } from './inspector-popover-header';
export { default as __experimentalUseOnBlockDrop } from './use-on-block-drop';

/*
* State Related Components
Expand Down
Expand Up @@ -11,7 +11,10 @@ import {
/**
* Internal dependencies
*/
import { getDistanceToNearestEdge } from '../../utils/math';
import {
getDistanceToNearestEdge,
isPointContainedByRect,
} from '../../utils/math';
import useOnBlockDrop from '../use-on-block-drop';
import { store as blockEditorStore } from '../../store';

Expand Down Expand Up @@ -48,23 +51,6 @@ import { store as blockEditorStore } from '../../store';
* 'inside' refers to nesting as an inner block.
*/

/**
* Is the point contained by the rectangle.
*
* @param {WPPoint} point The point.
* @param {DOMRect} rect The rectangle.
*
* @return {boolean} True if the point is contained by the rectangle, false otherwise.
*/
function isPointContainedByRect( point, rect ) {
return (
rect.left <= point.x &&
rect.right >= point.x &&
rect.top <= point.y &&
rect.bottom >= point.y
);
}

/**
* Determines whether the user positioning the dragged block to nest as an
* inner block.
Expand Down

0 comments on commit 96e5dc7

Please sign in to comment.