Skip to content

Commit 8aad3d7

Browse files
committed
feat: add <DropArea> component
1 parent eb65a3c commit 8aad3d7

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

src/DropArea/__story__/story.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {Component, createElement as h} from 'react';
2+
import {storiesOf} from '@storybook/react';
3+
import {action} from '@storybook/addon-actions';
4+
import {linkTo} from '@storybook/addon-links';
5+
import {DropArea} from '..';
6+
import ShowDocs from '../../../.storybook/ShowDocs'
7+
8+
storiesOf('UI/DropArea', module)
9+
// .add('Documentation', () => h(ShowDocs, {md: require('../../../docs/en/Toggle.md')}))
10+
.add('Example', () =>
11+
<DropArea
12+
onUri={action('onUri')}
13+
onText={action('onText')}
14+
onFiles={action('onFiles')}
15+
>
16+
<div style={{
17+
border: '1px solid tomato',
18+
height: 100
19+
}}>
20+
Drop here!
21+
</div>
22+
</DropArea>
23+
)

src/DropArea/index.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import {Component, cloneElement} from 'react';
2+
import {render} from 'react-universal-interface';
3+
import {h, noop} from '../util';
4+
5+
const REG_URL = /^https?:\/\//;
6+
7+
export interface IDropAreaProps {
8+
onFiles?: (files: File[], event?) => void;
9+
onText?: (text: string, event?) => void;
10+
onUri?: (url: string, event?) => void;
11+
}
12+
13+
export interface IDropAreaState {
14+
}
15+
16+
export class DropArea extends Component<IDropAreaProps, IDropAreaState> {
17+
static defaultProps = {
18+
onFiles: noop,
19+
onText: noop,
20+
onUrl: noop,
21+
};
22+
23+
mounted = true;
24+
25+
coponentWillUnmount () {
26+
this.mounted = false;
27+
}
28+
29+
onDragOver = (originalDragOver) => (event) => {
30+
(originalDragOver || noop)(event);
31+
event.preventDefault();
32+
};
33+
34+
onDragEnter = (originalDragEnter) => (event) => {
35+
(originalDragEnter || noop)(event);
36+
event.preventDefault();
37+
};
38+
39+
onDrop = (originalDrop) => (event) => {
40+
(originalDrop || noop)(event);
41+
event.preventDefault();
42+
43+
this.process(event.dataTransfer, event);
44+
const {dataTransfer} = event;
45+
};
46+
47+
onPaste = (originalOnPaste) => (event) => {
48+
(originalOnPaste || noop)(event);
49+
50+
this.process(event.clipboardData, event);
51+
};
52+
53+
process (dataTransfer: DataTransfer, event) {
54+
const uri = dataTransfer.getData('text/uri-list');
55+
56+
if (uri) {
57+
this.props.onUri(uri, event);
58+
return;
59+
}
60+
61+
if (dataTransfer.files && dataTransfer.files.length) {
62+
this.props.onFiles(Array.from(dataTransfer.files), event);
63+
return;
64+
}
65+
66+
if (dataTransfer.items && dataTransfer.items.length) {
67+
dataTransfer.items[0].getAsString((text) => {
68+
if (this.mounted) {
69+
this.props.onText(text);
70+
}
71+
});
72+
}
73+
}
74+
75+
render () {
76+
const element = render(this.props, {});
77+
const {props} = element;
78+
79+
return cloneElement(element, {
80+
...props,
81+
onDragOver: this.onDragOver(props.onDragOver),
82+
onDragEnter: this.onDragEnter(props.onDragEnter),
83+
onDrop: this.onDrop(props.onDrop),
84+
onPaste: this.onPaste(props.onPaste),
85+
});
86+
}
87+
}

0 commit comments

Comments
 (0)