From c367922d9c0d41d228e4c7a75b4f1c6377878a07 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Thu, 28 May 2020 17:18:50 +0300 Subject: [PATCH] Web: Common: added DragAndDrop component --- .../src/components/DragAndDrop/DragAndDrop.js | 93 +++++++++++++++++++ .../DragAndDrop/DragAndDrop.stories.js | 43 +++++++++ .../src/components/DragAndDrop/README.md | 28 ++++++ .../DragAndDrop/StyledDragAndDrop.js | 7 ++ .../src/components/DragAndDrop/index.js | 1 + 5 files changed, 172 insertions(+) create mode 100644 web/ASC.Web.Common/src/components/DragAndDrop/DragAndDrop.js create mode 100644 web/ASC.Web.Common/src/components/DragAndDrop/DragAndDrop.stories.js create mode 100644 web/ASC.Web.Common/src/components/DragAndDrop/README.md create mode 100644 web/ASC.Web.Common/src/components/DragAndDrop/StyledDragAndDrop.js create mode 100644 web/ASC.Web.Common/src/components/DragAndDrop/index.js diff --git a/web/ASC.Web.Common/src/components/DragAndDrop/DragAndDrop.js b/web/ASC.Web.Common/src/components/DragAndDrop/DragAndDrop.js new file mode 100644 index 0000000000..74a795fba5 --- /dev/null +++ b/web/ASC.Web.Common/src/components/DragAndDrop/DragAndDrop.js @@ -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 ( + + {children} + + ); + } +} + +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; diff --git a/web/ASC.Web.Common/src/components/DragAndDrop/DragAndDrop.stories.js b/web/ASC.Web.Common/src/components/DragAndDrop/DragAndDrop.stories.js new file mode 100644 index 0000000000..e160e4d0e7 --- /dev/null +++ b/web/ASC.Web.Common/src/components/DragAndDrop/DragAndDrop.stories.js @@ -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( + + Drop items here + + )}); diff --git a/web/ASC.Web.Common/src/components/DragAndDrop/README.md b/web/ASC.Web.Common/src/components/DragAndDrop/README.md new file mode 100644 index 0000000000..c0641f3005 --- /dev/null +++ b/web/ASC.Web.Common/src/components/DragAndDrop/README.md @@ -0,0 +1,28 @@ +# DragAndDrop + +Drag And Drop component can be used as Dropzone + +### Usage + +```js +import { DragAndDrop } from "asc-web-common"; +``` + +```jsx + + + Drop items here + + +``` + +### 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 | diff --git a/web/ASC.Web.Common/src/components/DragAndDrop/StyledDragAndDrop.js b/web/ASC.Web.Common/src/components/DragAndDrop/StyledDragAndDrop.js new file mode 100644 index 0000000000..48f46d9f00 --- /dev/null +++ b/web/ASC.Web.Common/src/components/DragAndDrop/StyledDragAndDrop.js @@ -0,0 +1,7 @@ +import styled from "styled-components"; + +const StyledDragAndDrop = styled.div` + border: ${props => props.drag && "1px dashed #bbb"}; +`; + +export default StyledDragAndDrop; diff --git a/web/ASC.Web.Common/src/components/DragAndDrop/index.js b/web/ASC.Web.Common/src/components/DragAndDrop/index.js new file mode 100644 index 0000000000..45805df6a5 --- /dev/null +++ b/web/ASC.Web.Common/src/components/DragAndDrop/index.js @@ -0,0 +1 @@ +export default from "./DragAndDrop"; \ No newline at end of file