Merge pull request #3783 from influxdata/refactor/drag-and-drop
Refactor drag and drop to listen for events directly on window.pull/10616/head
commit
a817565dd9
|
@ -1,6 +1,5 @@
|
|||
import React, {PureComponent, ReactElement, DragEvent} from 'react'
|
||||
import React, {PureComponent, ReactElement} from 'react'
|
||||
import classnames from 'classnames'
|
||||
// import {notifyDashboardUploadFailed} from 'src/shared/copy/notifications'
|
||||
|
||||
interface Props {
|
||||
fileTypesToAccept?: string
|
||||
|
@ -13,7 +12,6 @@ interface State {
|
|||
inputContent: string | null
|
||||
uploadContent: string
|
||||
fileName: string
|
||||
progress: string
|
||||
dragClass: string
|
||||
}
|
||||
|
||||
|
@ -32,41 +30,28 @@ class DragAndDrop extends PureComponent<Props, State> {
|
|||
inputContent: null,
|
||||
uploadContent: '',
|
||||
fileName: '',
|
||||
progress: '',
|
||||
dragClass: 'drag-none',
|
||||
}
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
window.addEventListener('dragover', this.handleWindowDragOver)
|
||||
window.addEventListener('drop', this.handleFileDrop)
|
||||
window.addEventListener('dragenter', this.handleDragEnter)
|
||||
window.addEventListener('dragleave', this.handleDragLeave)
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
window.removeEventListener('dragover', this.handleWindowDragOver)
|
||||
window.removeEventListener('drop', this.handleFileDrop)
|
||||
window.removeEventListener('dragenter', this.handleDragEnter)
|
||||
window.removeEventListener('dragleave', this.handleDragLeave)
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div className={this.containerClass}>
|
||||
{/* (Invisible, covers entire screen)
|
||||
This div handles drag only*/}
|
||||
<div
|
||||
onDrop={this.handleFile(true)}
|
||||
onDragOver={this.handleDragOver}
|
||||
onDragEnter={this.handleDragEnter}
|
||||
onDragExit={this.handleDragLeave}
|
||||
onDragLeave={this.handleDragLeave}
|
||||
className="drag-and-drop--dropzone"
|
||||
/>
|
||||
{/* visible form, handles drag & click */}
|
||||
{this.dragArea}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private get dragArea(): ReactElement<HTMLDivElement> {
|
||||
return (
|
||||
<div
|
||||
className={this.dragAreaClass}
|
||||
onClick={this.handleFileOpen}
|
||||
onDrop={this.handleFile(true)}
|
||||
onDragOver={this.handleDragOver}
|
||||
onDragEnter={this.handleDragEnter}
|
||||
onDragExit={this.handleDragLeave}
|
||||
onDragLeave={this.handleDragLeave}
|
||||
>
|
||||
<div className={this.dragAreaClass} onClick={this.handleFileOpen}>
|
||||
{this.dragAreaHeader}
|
||||
<div className={this.infoClass} />
|
||||
<input
|
||||
|
@ -74,13 +59,18 @@ class DragAndDrop extends PureComponent<Props, State> {
|
|||
ref={r => (this.fileInput = r)}
|
||||
className="drag-and-drop--input"
|
||||
accept={this.fileTypesToAccept}
|
||||
onChange={this.handleFile(false)}
|
||||
onChange={this.handleFileClick}
|
||||
/>
|
||||
{this.buttons}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private handleWindowDragOver = (event: DragEvent) => {
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
private get fileTypesToAccept(): string {
|
||||
const {fileTypesToAccept} = this.props
|
||||
|
||||
|
@ -153,16 +143,31 @@ class DragAndDrop extends PureComponent<Props, State> {
|
|||
handleSubmit(uploadContent, fileName)
|
||||
}
|
||||
|
||||
private handleFile = (drop: boolean) => (e: any): void => {
|
||||
let file
|
||||
if (drop) {
|
||||
file = e.dataTransfer.files[0]
|
||||
private handleFileClick = (e: any): void => {
|
||||
const file = e.currentTarget.files[0]
|
||||
|
||||
if (!file) {
|
||||
return
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
const reader = new FileReader()
|
||||
reader.readAsText(file)
|
||||
reader.onload = loadEvent => {
|
||||
this.setState({
|
||||
uploadContent: loadEvent.target.result,
|
||||
fileName: file.name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private handleFileDrop = (e: any): void => {
|
||||
const file = e.dataTransfer.files[0]
|
||||
this.setState({
|
||||
dragClass: 'drag-none',
|
||||
})
|
||||
} else {
|
||||
file = e.currentTarget.files[0]
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
return
|
||||
|
@ -193,18 +198,13 @@ class DragAndDrop extends PureComponent<Props, State> {
|
|||
this.fileInput.value = ''
|
||||
}
|
||||
|
||||
private handleDragOver = (e: DragEvent<HTMLDivElement>) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
||||
private handleDragEnter = (e: DragEvent<HTMLDivElement>): void => {
|
||||
private handleDragEnter = (e: DragEvent): void => {
|
||||
dragCounter += 1
|
||||
e.preventDefault()
|
||||
this.setState({dragClass: 'drag-over'})
|
||||
}
|
||||
|
||||
private handleDragLeave = (e: DragEvent<HTMLDivElement>): void => {
|
||||
private handleDragLeave = (e: DragEvent): void => {
|
||||
dragCounter -= 1
|
||||
e.preventDefault()
|
||||
if (dragCounter === 0) {
|
||||
|
|
|
@ -3,16 +3,6 @@
|
|||
------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
.drag-and-drop--dropzone {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 1000%;
|
||||
height: 1000%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: $drag-and-drop--z-dropzone;
|
||||
}
|
||||
|
||||
.drag-and-drop--form {
|
||||
position: relative;
|
||||
z-index: $drag-and-drop--z-form;
|
||||
|
@ -69,7 +59,9 @@ input[type='file'].drag-and-drop--input {
|
|||
flex-wrap: nowrap;
|
||||
margin-top: 18px;
|
||||
|
||||
> button.btn {margin: 0 4px;}
|
||||
> button.btn {
|
||||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue