-
Notifications
You must be signed in to change notification settings - Fork 0
/
preact_example.tsx
59 lines (51 loc) · 1.49 KB
/
preact_example.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import type { FunctionalComponent } from "preact";
import { useState, useEffect, useRef, useCallback } from "preact/hooks";
import { create } from "@krofdrakula/drop";
interface PreviewProps {
sources: string[];
}
const Preview: FunctionalComponent<PreviewProps> = ({ sources }) => {
return (
<ul>
{sources.map((src) => (
<li>
<img src={src} />
</li>
))}
</ul>
);
};
interface DropTargetProps {
onDrop: (files: Map<string, File>) => void;
}
// this component provides the drop target for files
const DropTarget: FunctionalComponent<DropTargetProps> = ({ onDrop }) => {
const dropTarget = useRef<HTMLDivElement>();
useEffect(() => {
if (!dropTarget.current) return;
return create(dropTarget.current, { onDrop });
}, [dropTarget.current, onDrop]);
// @ts-ignore refs have incompatible null/undefined types here
return <div ref={dropTarget}>Drop files here</div>;
};
const Demo = () => {
const [sources, setSources] = useState<string[]>([]);
const onDrop = useCallback(
(files: Map<string, File>) => {
setSources((currentSources) => {
// release all current object URLs to free memory
for (const url of currentSources) URL.revokeObjectURL(url);
// set the new URLs
return [...files.values()].map((file) => URL.createObjectURL(file));
});
},
[setSources]
);
return (
<>
<DropTarget onDrop={onDrop} />
<Preview sources={sources} />
</>
);
};
export default Demo;