/
index.tsx
100 lines (89 loc) · 2.21 KB
/
index.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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import React, { useState, useCallback } from 'react'
import { NativeTypes } from 'react-dnd-html5-backend'
import Dustbin from './Dustbin'
import Box from './Box'
import ItemTypes from './ItemTypes'
import update from 'immutability-helper'
interface DustbinState {
accepts: string[]
lastDroppedItem: any
}
interface BoxState {
name: string
type: string
}
export interface ContainerState {
droppedBoxNames: string[]
dustbins: Array<{
accepts: string[]
lastDroppedItem: any
}>
boxes: Array<{
name: string
type: string
}>
}
const Container: React.FC = () => {
const [dustbins, setDustbins] = useState<DustbinState[]>([
{ accepts: [ItemTypes.GLASS], lastDroppedItem: null },
{ accepts: [ItemTypes.FOOD], lastDroppedItem: null },
{
accepts: [ItemTypes.PAPER, ItemTypes.GLASS, NativeTypes.URL],
lastDroppedItem: null,
},
{ accepts: [ItemTypes.PAPER, NativeTypes.FILE], lastDroppedItem: null },
])
const [boxes] = useState<BoxState[]>([
{ name: 'Bottle', type: ItemTypes.GLASS },
{ name: 'Banana', type: ItemTypes.FOOD },
{ name: 'Magazine', type: ItemTypes.PAPER },
])
const [droppedBoxNames, setDroppedBoxNames] = useState<string[]>([])
function isDropped(boxName: string) {
return droppedBoxNames.indexOf(boxName) > -1
}
const handleDrop = useCallback(
(index: number, item: { name: string }) => {
const { name } = item
setDroppedBoxNames(
update(droppedBoxNames, name ? { $push: [name] } : { $push: [] }),
)
setDustbins(
update(dustbins, {
[index]: {
lastDroppedItem: {
$set: item,
},
},
}),
)
},
[droppedBoxNames, dustbins],
)
return (
<div>
<div style={{ overflow: 'hidden', clear: 'both' }}>
{dustbins.map(({ accepts, lastDroppedItem }, index) => (
<Dustbin
accept={accepts}
lastDroppedItem={lastDroppedItem}
// tslint:disable-next-line jsx-no-lambda
onDrop={item => handleDrop(index, item)}
key={index}
/>
))}
</div>
<div style={{ overflow: 'hidden', clear: 'both' }}>
{boxes.map(({ name, type }, index) => (
<Box
name={name}
type={type}
isDropped={isDropped(name)}
key={index}
/>
))}
</div>
</div>
)
}
export default Container