@wordpress/components
Version:
UI components for WordPress.
102 lines (91 loc) • 2.58 kB
JavaScript
/**
* External dependencies
*/
import classnames from 'classnames';
import { includes } from 'lodash';
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { upload, Icon } from '@wordpress/icons';
import { getFilesFromDataTransfer } from '@wordpress/dom';
import { __experimentalUseDropZone as useDropZone } from '@wordpress/compose';
export default function DropZoneComponent( {
className,
label,
onFilesDrop,
onHTMLDrop,
onDrop,
} ) {
const [ isDraggingOverDocument, setIsDraggingOverDocument ] = useState();
const [ isDraggingOverElement, setIsDraggingOverElement ] = useState();
const [ type, setType ] = useState();
const ref = useDropZone( {
onDrop( event ) {
const files = getFilesFromDataTransfer( event.dataTransfer );
const html = event.dataTransfer.getData( 'text/html' );
if ( files.length && onFilesDrop ) {
onFilesDrop( files );
} else if ( html && onHTMLDrop ) {
onHTMLDrop( html );
} else if ( onDrop ) {
onDrop( event );
}
},
onDragStart( event ) {
setIsDraggingOverDocument( true );
let _type = 'default';
if (
// Check for the types because sometimes the files themselves
// are only available on drop.
includes( event.dataTransfer.types, 'Files' ) ||
getFilesFromDataTransfer( event.dataTransfer ).length > 0
) {
_type = 'file';
} else if ( includes( event.dataTransfer.types, 'text/html' ) ) {
_type = 'html';
}
setType( _type );
},
onDragEnd() {
setIsDraggingOverDocument( false );
setType();
},
onDragEnter() {
setIsDraggingOverElement( true );
},
onDragLeave() {
setIsDraggingOverElement( false );
},
} );
let children;
if ( isDraggingOverElement ) {
children = (
<div className="components-drop-zone__content">
<Icon
icon={ upload }
className="components-drop-zone__content-icon"
/>
<span className="components-drop-zone__content-text">
{ label ? label : __( 'Drop files to upload' ) }
</span>
</div>
);
}
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 (
<div ref={ ref } className={ classes }>
{ children }
</div>
);
}