- { children }
+ if ( isDraggingOverElement ) {
+ children = (
+
+
+
+ { label ? label : __( 'Drop files to upload' ) }
+
);
}
+
+ const classes = classnames( 'components-drop-zone', className, {
+ 'is-active': ( isDraggingOverDocument || isDraggingOverElement ) && (
+ ( type === 'file' && onFilesDrop ) ||
+ ( type === 'html' && onHTMLDrop ) ||
+ ( type === 'default' && onDrop )
+ ),
+ 'is-dragging-over-document': isDraggingOverDocument,
+ 'is-dragging-over-element': isDraggingOverElement,
+ [ `is-dragging-${ type }` ]: !! type,
+ } );
+
+ return (
+
+ { children }
+
+ );
}
export default DropZone;
diff --git a/packages/components/src/drop-zone/provider.js b/packages/components/src/drop-zone/provider.js
index a0df1364b8ac7..45c0a70749c38 100644
--- a/packages/components/src/drop-zone/provider.js
+++ b/packages/components/src/drop-zone/provider.js
@@ -9,11 +9,13 @@ import { isEqual, find, some, filter, throttle, includes } from 'lodash';
import { Component, createContext } from '@wordpress/element';
import isShallowEqual from '@wordpress/is-shallow-equal';
-const { Provider, Consumer } = createContext( {
+export const Context = createContext( {
addDropZone: () => {},
removeDropZone: () => {},
} );
+const { Provider, Consumer } = Context;
+
const getDragEventType = ( { dataTransfer } ) => {
if ( dataTransfer ) {
// Use lodash `includes` here as in the Edge browser `types` is implemented
@@ -126,25 +128,20 @@ class DropZoneProvider extends Component {
// Index of hovered dropzone.
const hoveredDropZones = filter( this.dropZones, ( dropZone ) =>
isTypeSupportedByDropZone( dragEventType, dropZone ) &&
- isWithinElementBounds( dropZone.element, detail.clientX, detail.clientY )
+ isWithinElementBounds( dropZone.element.current, detail.clientX, detail.clientY )
);
// Find the leaf dropzone not containing another dropzone
const hoveredDropZone = find( hoveredDropZones, ( zone ) => (
- ! some( hoveredDropZones, ( subZone ) => subZone !== zone && zone.element.parentElement.contains( subZone.element ) )
+ ! some( hoveredDropZones, ( subZone ) => subZone !== zone && zone.element.current.parentElement.contains( subZone.element.current ) )
) );
const hoveredDropZoneIndex = this.dropZones.indexOf( hoveredDropZone );
let position = null;
- if ( hoveredDropZone ) {
- const rect = hoveredDropZone.element.getBoundingClientRect();
-
- position = {
- x: detail.clientX - rect.left < rect.right - detail.clientX ? 'left' : 'right',
- y: detail.clientY - rect.top < rect.bottom - detail.clientY ? 'top' : 'bottom',
- };
+ if ( hoveredDropZone && hoveredDropZone.withPosition ) {
+ position = { x: detail.clientX, y: detail.clientY };
}
// Optimisation: Only update the changed dropzones
diff --git a/packages/components/src/index.js b/packages/components/src/index.js
index 8fb840d437200..d59d33984f16c 100644
--- a/packages/components/src/index.js
+++ b/packages/components/src/index.js
@@ -22,7 +22,7 @@ export { DateTimePicker, DatePicker, TimePicker } from './date-time';
export { default as __experimentalDimensionControl } from './dimension-control';
export { default as Disabled } from './disabled';
export { default as Draggable } from './draggable';
-export { default as DropZone } from './drop-zone';
+export { default as DropZone, useDropZone as __unstableUseDropZone } from './drop-zone';
export { default as DropZoneProvider } from './drop-zone/provider';
export { default as Dropdown } from './dropdown';
export { default as DropdownMenu } from './dropdown-menu';