Skip to content

Commit 8f3fa25

Browse files
committed
Context
1 parent 97edf85 commit 8f3fa25

File tree

8 files changed

+140
-152
lines changed

8 files changed

+140
-152
lines changed

index.html

-10
This file was deleted.

public/bg.jpg

4 MB
Loading

src/App.tsx

+34-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react'
1+
import React, {useState} from 'react'
22
import styled from 'styled-components'
33

44
import {Canvas} from './Canvas'
@@ -13,14 +13,41 @@ const Container = styled.div`
1313
height: 100vh;
1414
`
1515

16+
type Element = {
17+
id: number
18+
top: number
19+
left: number
20+
}
21+
22+
type SelectedElement = number | undefined
23+
24+
type ElementsContext = {
25+
elements: Element[]
26+
setElements: React.Dispatch<React.SetStateAction<Element[]>>
27+
selectedElement: SelectedElement
28+
setSelectedElement: React.Dispatch<React.SetStateAction<number | undefined>>
29+
}
30+
31+
export const ElementsContext = React.createContext<ElementsContext>({
32+
elements: [],
33+
setElements: () => {},
34+
selectedElement: undefined,
35+
setSelectedElement: () => {},
36+
})
37+
1638
const App: React.FC = () => {
39+
const [elements, setElements] = useState<Element[]>([])
40+
const [selectedElement, setSelectedElement] = useState<number | undefined>()
41+
1742
return (
18-
<Container>
19-
<LeftSidebar />
20-
<Canvas />
21-
<RightSidebar />
22-
<GlobalStyles />
23-
</Container>
43+
<ElementsContext.Provider value={{elements, setElements, selectedElement, setSelectedElement}}>
44+
<Container>
45+
<LeftSidebar />
46+
<Canvas />
47+
<RightSidebar />
48+
<GlobalStyles />
49+
</Container>
50+
</ElementsContext.Provider>
2451
)
2552
}
2653

src/Canvas.tsx

+28-14
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,43 @@
1-
import React, {useState} from 'react'
1+
import React, {useContext} from 'react'
22
import styled from 'styled-components'
33
import {Element} from './Element'
4+
import {ElementsContext} from './App'
45

56
const CanvasContainer = styled.div`
67
flex: 1;
78
position: relative;
89
`
910

10-
export const Canvas: React.FC = ({children}) => {
11-
const [backgroundColor] = useState('#101010')
12-
const [elements] = useState<number[]>([])
11+
export const Canvas: React.FC = () => {
12+
const {elements, setSelectedElement, setElements} = useContext(ElementsContext)
1313

1414
return (
15-
<CanvasContainer
16-
style={{backgroundColor}}
17-
onClick={(e) => {
18-
if (e.target === e.currentTarget) {
19-
// Deselect all elements
20-
}
21-
}}
22-
>
15+
<CanvasContainer>
2316
{elements.map((element) => {
24-
return <Element key={element} id={element} />
17+
return (
18+
<Element
19+
key={element.id}
20+
top={element.top}
21+
left={element.left}
22+
onDrag={(top, left) => {
23+
setElements(
24+
elements.map((el) => {
25+
if (el.id === element.id) {
26+
return {
27+
...el,
28+
top,
29+
left,
30+
}
31+
} else {
32+
return el
33+
}
34+
}),
35+
)
36+
}}
37+
onSelect={() => setSelectedElement(element.id)}
38+
/>
39+
)
2540
})}
26-
{children}
2741
</CanvasContainer>
2842
)
2943
}

src/Element.tsx

+26-45
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
1-
import React, {useState} from 'react'
1+
import React from 'react'
22
import {DraggableCore} from 'react-draggable'
33
import styled from 'styled-components'
44

55
const Container = styled.div`
66
position: absolute;
7+
box-shadow: 0 5px 20px 0 rgba(0, 0, 0, 0.3);
8+
border-radius: 20px;
9+
width: 200px;
10+
height: 170px;
11+
background-color: rgba(60, 60, 60, 0.4);
12+
backdrop-filter: blur(20px);
13+
`
14+
15+
const InnerContainer = styled.div`
16+
width: 100%;
17+
height: 100%;
718
display: flex;
819
align-items: center;
920
justify-content: center;
10-
box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.1);
1121
`
1222

1323
const Label = styled.input`
@@ -20,50 +30,21 @@ const Label = styled.input`
2030
color: #fff;
2131
`
2232

23-
export const Element: React.FC<{id: number}> = ({id}) => {
24-
const [element, setElement] = useState({
25-
label: 'Hello world',
26-
size: {width: 250, height: 150},
27-
position: {top: 0, left: 0},
28-
fill: '#2E2E2F',
29-
})
33+
type ElementProps = {
34+
top: number
35+
left: number
36+
onDrag: (top: number, left: number) => void
37+
onSelect: () => void
38+
}
3039

40+
export const Element: React.FC<ElementProps> = ({top, left, onDrag, onSelect}) => {
3141
return (
32-
<DraggableCore
33-
onDrag={(e: any) => {
34-
setElement((el: any) => ({
35-
...el,
36-
position: {
37-
top: el.position.top + e.movementY,
38-
left: el.position.left + e.movementX,
39-
},
40-
}))
41-
}}
42-
>
43-
<div>
44-
<Container
45-
style={{
46-
backgroundColor: element.fill,
47-
...element.size,
48-
...element.position,
49-
}}
50-
onMouseDown={() => {
51-
// Set selected
52-
}}
53-
>
54-
<Label
55-
value={element.label}
56-
onMouseDown={(e) => e.stopPropagation()}
57-
onClick={(e) => e.stopPropagation()}
58-
onChange={(e) =>
59-
setElement((el: any) => ({
60-
...el,
61-
label: e.currentTarget.value,
62-
}))
63-
}
64-
/>
65-
</Container>
66-
</div>
67-
</DraggableCore>
42+
<Container style={{top, left}} onMouseDown={onSelect}>
43+
<DraggableCore onDrag={(e: any) => onDrag(top + e.movementY, left + e.movementX)}>
44+
<InnerContainer>
45+
<Label value="Hello world" />
46+
</InnerContainer>
47+
</DraggableCore>
48+
</Container>
6849
)
6950
}

src/LeftSidebar.tsx

+18-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
import React, {useState} from 'react'
1+
import React, {useContext} from 'react'
22
import {Sidebar, Title} from './ui'
33
import styled from 'styled-components'
44
import {FiSquare, FiImage} from 'react-icons/fi'
5+
import {ElementsContext} from './App'
56

67
const InsertButton = styled.button`
7-
width: 40px;
8-
height: 40px;
9-
background-color: #565656;
10-
border-radius: 3px;
8+
width: 60px;
9+
height: 60px;
10+
background-color: rgba(10, 10, 10, 0.3);
11+
border-radius: 15px;
1112
display: flex;
1213
align-items: center;
1314
justify-content: center;
@@ -17,24 +18,31 @@ const InsertButton = styled.button`
1718
`
1819

1920
export const LeftSidebar: React.FC = () => {
20-
const [elements, setElements] = useState<number[]>([])
21+
const {setElements} = useContext(ElementsContext)
2122

2223
return (
2324
<Sidebar>
2425
<Title>Insert</Title>
2526
<div style={{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
2627
<InsertButton
2728
onClick={() => {
28-
setElements((elements: number[]) => {
29-
return [...elements, elements.length]
29+
setElements((elements) => {
30+
return [
31+
...elements,
32+
{
33+
id: elements.length,
34+
top: 0,
35+
left: 0,
36+
},
37+
]
3038
})
3139
}}
3240
>
33-
<FiSquare color="white" size={30} />
41+
<FiSquare color="white" size={35} />
3442
</InsertButton>
3543
<div style={{width: 15}} />
3644
<InsertButton>
37-
<FiImage color="white" size={30} />
45+
<FiImage color="white" size={35} />
3846
</InsertButton>
3947
</div>
4048
</Sidebar>

0 commit comments

Comments
 (0)