Web: Common: added DragAndDrop component

This commit is contained in:
Nikita Gopienko 2020-05-28 17:18:50 +03:00
parent 4ac1fd815a
commit c367922d9c
5 changed files with 172 additions and 0 deletions

View File

@ -0,0 +1,93 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import StyledDragAndDrop from "./StyledDragAndDrop";
class DragAndDrop extends Component {
state = { drag: false };
dropRef = React.createRef();
dragCounter = 0;
onDragOver = (e) => {
e.stopPropagation();
e.preventDefault();
//this.dragCounter++;
this.props.onDragOver && this.props.onDragOver(e);
};
onDragEnter = (e) => {
this.dragCounter++;
e.stopPropagation();
e.preventDefault();
this.props.onDragEnter && this.props.onDragEnter(e);
this.setState({ drag: true });
};
onDragLeave = (e) => {
this.dragCounter--;
if(this.dragCounter === 0) {
this.setState({ drag: false });
}
this.props.onDragLeave && this.props.onDragLeave(e);
e.stopPropagation();
e.preventDefault();
};
onDrop = (e) => {
e.preventDefault();
e.stopPropagation();
this.setState({ drag: false });
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
this.props.onDrop && this.props.onDrop(e);
e.dataTransfer.clearData();
this.dragCounter = 0;
}
};
onDragStart = (e) => {
this.props.onDragStart && this.props.onDragStart(e);
};
componentDidMount() {
let div = this.dropRef.current;
div.addEventListener("dragstart", this.onDragStart, false);
div.addEventListener("dragenter", this.onDragEnter);
div.addEventListener("dragleave", this.onDragLeave);
div.addEventListener("dragover", this.onDragOver);
div.addEventListener("drop", this.onDrop);
}
componentWillUnmount() {
let div = this.dropRef.current;
div.removeEventListener("dragstart", this.onDragStart, false);
div.removeEventListener("dragenter", this.onDragEnter);
div.removeEventListener("dragleave", this.onDragLeave);
div.removeEventListener("dragover", this.onDragOver);
div.removeEventListener("drop", this.onDrop);
}
render() {
//console.log("DND render");
const { children, draggable, ...rest } = this.props;
return (
<StyledDragAndDrop className="drag-and-drop" drag={this.state.drag} draggable={draggable} {...rest} ref={this.dropRef}>
{children}
</StyledDragAndDrop>
);
}
}
DragAndDrop.propTypes = {
children: PropTypes.any,
draggable: PropTypes.bool,
onDragStart: PropTypes.func,
onDragEnter: PropTypes.func,
onDragLeave: PropTypes.func,
onDragOver: PropTypes.func,
onDrop: PropTypes.func
}
export default DragAndDrop;

View File

@ -0,0 +1,43 @@
import React from "react";
import { storiesOf } from "@storybook/react";
import withReadme from "storybook-readme/with-readme";
import Readme from "./README.md";
import DragAndDrop from "./";
import { Text } from "asc-web-components";
storiesOf("Components| DragAndDrop", module)
.addDecorator(withReadme(Readme))
.add("base", () => {
const traverseFileTree = (item, path) => {
if (item.isFile) {
item.file(file => console.log("File:", path + file.name));
} else if (item.isDirectory) {
const dirReader = item.createReader();
dirReader.readEntries(entries => {
for (let i = 0; i < entries.length; i++) {
traverseFileTree(entries[i], path + item.name + "/");
}
});
}
}
const onDrop = event => {
console.log("onDrop", event);
const items = event.dataTransfer.items;
for (let i = 0; i < items.length; i++) {
const item = items[i].webkitGetAsEntry();
if (item) {
traverseFileTree(item, "");
}
}
}
const dropDownStyles = { margin: 16, width: 200, height: 200, border: "5px solid #999" };
const textStyles = {textAlign: "center", lineHeight: "9.5em"};
return(
<DragAndDrop onDrop={onDrop} style={dropDownStyles}>
<Text style={textStyles} color="#999" fontSize="20px">Drop items here</Text>
</DragAndDrop>
)});

View File

@ -0,0 +1,28 @@
# DragAndDrop
Drag And Drop component can be used as Dropzone
### Usage
```js
import { DragAndDrop } from "asc-web-common";
```
```jsx
<DragAndDrop onDrop={onDrop} style={width: 200, height: 200, border: "5px solid #999"}>
<Text style={textStyles} color="#999" fontSize="20px">
Drop items here
</Text>
</DragAndDrop>
```
### Properties
| Props | Type | Required | Values | Default | Description |
| ------------- | :--------: | :------: | :----: | :-----: | ------------------------------------------------------------- |
| `draggable` | `bool` | | | `false` | Sets the value of the draggable attribute to true |
| `onDragStart` | `function` | | | | Occurs when the user starts to drag an element |
| `onDragEnter` | `function` | | | | Occurs when the dragged element enters the drop target |
| `onDragLeave` | `function` | | | | Occurs when the dragged element leaves the drop target |
| `onDragOver` | `function` | | | | Occurs when the dragged element is over the drop target |
| `onDrop` | `function` | | | | Occurs when the dragged element is dropped on the drop target |

View File

@ -0,0 +1,7 @@
import styled from "styled-components";
const StyledDragAndDrop = styled.div`
border: ${props => props.drag && "1px dashed #bbb"};
`;
export default StyledDragAndDrop;

View File

@ -0,0 +1 @@
export default from "./DragAndDrop";