Skip to content

Commit 5aa3ae5

Browse files
committed
2 parents 8e30232 + 59ec69c commit 5aa3ae5

File tree

16 files changed

+469
-26
lines changed

16 files changed

+469
-26
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ $RECYCLE.BIN/
158158

159159
#VSCode
160160
.vscode/
161+
reactype.code-workspace
161162

162163
# User-specific files
163164
*.suo

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@
147147
"react": "^16.13.0",
148148
"react-ace": "^8.1.0",
149149
"react-d3-tree": "^1.12.3",
150+
"react-dnd": "^11.1.3",
151+
"react-dnd-html5-backend": "^11.1.3",
150152
"react-dom": "^16.4.1",
151153
"react-draggable": "^3.0.5",
152154
"react-konva": "^16.12.0-0",

src/components/AppNew.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React, { useState } from 'react';
2+
import '../public/styles/style.css';
3+
import '../public/styles/styleNew.css';
4+
import { DndProvider } from 'react-dnd';
5+
import { HTML5Backend } from 'react-dnd-html5-backend';
6+
import AppContainer from '../containers/AppContainer';
7+
import { initialState, stateContext } from '../context/context';
8+
// import { Context } from '../interfaces/InterfacesNew';
9+
10+
// Intermediary component to wrap main App component with higher order provider components
11+
export const App = (): JSX.Element => {
12+
const [context, setContext] = useState(initialState);
13+
return (
14+
<div className="app">
15+
<DndProvider backend={HTML5Backend}>
16+
<header
17+
style={{ height: '40px', width: '100%', backgroundColor: 'white' }}
18+
>
19+
ReacType
20+
</header>
21+
<stateContext.Provider value={[context, setContext]}>
22+
<AppContainer />
23+
</stateContext.Provider>
24+
</DndProvider>
25+
</div>
26+
);
27+
};
28+
29+
export default App;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
import Grid from '@material-ui/core/Grid';
3+
4+
import { useDrag } from 'react-dnd';
5+
import { ItemTypes } from '../../constants/ItemTypes';
6+
7+
const ComponentPanelItem = (): JSX.Element => {
8+
// useDrag hook allows components in left panel to be drag source
9+
const [{ isDragging }, drag] = useDrag({
10+
item: {
11+
type: ItemTypes.INSTANCE,
12+
newInstance: true
13+
// category,
14+
},
15+
collect: (monitor: any) => ({
16+
isDragging: !!monitor.isDragging()
17+
})
18+
});
19+
return (
20+
<Grid
21+
item
22+
ref={drag}
23+
xs={12}
24+
style={{
25+
color: 'white',
26+
// this is experimental for version: BLADERUNNER THEME
27+
backgroundColor: 'none',
28+
borderRadius: '10px',
29+
// minWidth: '340px',
30+
minHeight: '100px',
31+
border: '2px solid white'
32+
}}
33+
>
34+
Component Panel
35+
</Grid>
36+
);
37+
};
38+
39+
export default ComponentPanelItem;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from 'react';
2+
3+
import Grid from '@material-ui/core/Grid';
4+
5+
import ComponentPanelItem from './ComponentPanelItemNew';
6+
7+
const ComponentPanel = (): JSX.Element => {
8+
return (
9+
<Grid
10+
container
11+
direction="row"
12+
justify="center"
13+
alignItems="center"
14+
style={{
15+
minWidth: '470px',
16+
padding: '20px'
17+
}}
18+
>
19+
<ComponentPanelItem />
20+
<ComponentPanelItem />
21+
<ComponentPanelItem />
22+
</Grid>
23+
// </div>
24+
);
25+
}
26+
27+
export default ComponentPanel;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React, { useRef, useMemo, useContext } from 'react';
2+
import { useDrag, useDrop, DropTargetMonitor } from 'react-dnd';
3+
import { ItemTypes } from '../../constants/ItemTypes';
4+
import { stateContext } from '../../context/context';
5+
import { updateInstance } from '../../helperFunctions/instances';
6+
import { ComponentInstance } from '../../interfaces/interfacesNew';
7+
8+
9+
const CanvasComponent = ({
10+
id,
11+
style,
12+
children
13+
}: ComponentInstance): JSX.Element => {
14+
const ref = useRef(null);
15+
const pageId = 1;
16+
17+
const [context, setContext] = useContext(stateContext);
18+
// both useDrop and useDrag used here to allow canvas components to be both a drop target and drag source
19+
const [{ isOver }, drop] = useDrop({
20+
accept: ItemTypes.INSTANCE,
21+
// triggered on drop
22+
drop: (item: any, monitor: DropTargetMonitor) => {
23+
const didDrop = monitor.didDrop();
24+
if (didDrop) {
25+
return;
26+
}
27+
const hoverId = id;
28+
// updates state with new instance
29+
setContext(updateInstance(hoverId, item, context, pageId));
30+
},
31+
collect: (monitor: any) => ({
32+
isOver: !!monitor.isOver({ shallow: true })
33+
})
34+
});
35+
36+
const [{ isDragging }, drag] = useDrag({
37+
// setting item attributes to be referenced when updating state with new instance of dragged item
38+
item: {
39+
type: ItemTypes.INSTANCE,
40+
newInstance: false,
41+
id: id
42+
},
43+
// canDrag: !props.children.length,
44+
collect: (monitor: any) => ({
45+
isDragging: !!monitor.isDragging()
46+
})
47+
});
48+
49+
const elementStyle = useMemo(
50+
() => ({
51+
// ...props.style,
52+
borderStyle: isOver ? 'dotted' : 'solid',
53+
opacity: isDragging ? 0.5 : 1
54+
}),
55+
[isDragging, isOver]
56+
);
57+
58+
drag(drop(ref));
59+
return (
60+
<div ref={ref} className="componentDefault" style={elementStyle}>
61+
I am a Canvas Component! :D
62+
{children}
63+
</div>
64+
);
65+
};
66+
67+
export default CanvasComponent;

src/components/main/MainCanvasNew.tsx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import React, { useMemo, useContext } from 'react';
2+
import { useDrop } from 'react-dnd';
3+
import { ItemTypes } from '../../constants/ItemTypes';
4+
import { stateContext } from '../../context/context';
5+
import { updateInstance } from '../../helperFunctions/instances';
6+
import CanvasComponent from './CanvasComponentNew';
7+
8+
//renders canvas components based on state
9+
const renderCanvas = (state, page) => {
10+
// get page ID and assign data to children
11+
let pageData;
12+
for (let i = 0; i <= state.pages.length - 1; i++) {
13+
if (state.pages[i]['pageId'] === page) {
14+
pageData = state.pages[i];
15+
break;
16+
}
17+
}
18+
// if there is no page or the page has no children, end the function
19+
if (!pageData || !pageData.children) return;
20+
// iterate through each child on the page ID and render each component
21+
return pageData.children.map(component => renderComponent(component));
22+
};
23+
24+
// renders an instance in the instance tree. If instance has children, those instances will also be rendered recursively
25+
const renderComponent = component => {
26+
const { id, style } = component;
27+
28+
// const style = { border: '5px solid pink', margin: '40px' };
29+
return (
30+
<CanvasComponent id={id} style={style} key={id}>
31+
{/* render all children of component */}
32+
{component.children.map(comp => renderComponent(comp))}
33+
</CanvasComponent>
34+
);
35+
};
36+
37+
function MainCanvas() {
38+
let pageId = 1;
39+
const [context, setContext] = useContext(stateContext);
40+
// useDrop hook allows main canvas to be a drop target
41+
const [{ isOver }, drop] = useDrop({
42+
accept: ItemTypes.INSTANCE,
43+
drop: (item, monitor) => {
44+
const didDrop = monitor.didDrop(); // returns false for direct drop target
45+
if (didDrop) {
46+
return;
47+
}
48+
setContext(updateInstance(null, item, context, pageId));
49+
},
50+
collect: monitor => ({
51+
isOver: !!monitor.isOver()
52+
})
53+
});
54+
const mainCanvasStyle = useMemo(
55+
() => ({
56+
height: '1000px',
57+
width: '1000px',
58+
backgroundColor: 'white',
59+
border: '2px solid black',
60+
borderStyle: isOver ? 'dotted' : 'solid'
61+
}),
62+
[isOver]
63+
);
64+
return (
65+
<div ref={drop} style={mainCanvasStyle}>
66+
{renderCanvas(context, 1)}
67+
</div>
68+
);
69+
}
70+
71+
export default MainCanvas;

src/constants/ItemTypes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const ItemTypes = {
2+
INSTANCE: 'instance'
3+
};
4+
5+
export { ItemTypes };

src/containers/AppContainer.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { MuiThemeProvider } from '@material-ui/core/styles';
44
import LinearProgress from '@material-ui/core/LinearProgress';
55
import Tutorial from '../components/main/Tutorial';
66
import LeftContainer from './LeftContainer';
7+
import LeftContainerNew from './LeftContainerNew';
78
import MainContainer from './MainContainer';
89
import RightContainer from './RightContainer';
910
import theme from '../theme';
@@ -180,12 +181,7 @@ class AppContainer extends Component<Props, State> {
180181
handleNext={this.handleNext}
181182
/>
182183
<div className="app-container">
183-
<LeftContainer //The left side-bar that contains the component cards and the buttons.
184-
components={components}
185-
totalComponents={totalComponents}
186-
focusComponent={focusComponent} //'focused' just means it's the one currently selected.
187-
selectableChildren={selectableChildren} //this toggles whether a component can be added as a child to the focused component
188-
/>
184+
<LeftContainerNew />
189185
<MainContainer
190186
components={components}
191187
image={this.state.image}

src/containers/LeftContainerNew.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from 'react';
2+
3+
import Grid from '@material-ui/core/Grid';
4+
import TextField from '@material-ui/core/TextField';
5+
import Button from '@material-ui/core/Button';
6+
import AddIcon from '@material-ui/icons/Add';
7+
import Fab from '@material-ui/core/Fab';
8+
import FormControlLabel from '@material-ui/core/FormControlLabel';
9+
10+
import ComponentPanel from '../components/left/ComponentPanelNew';
11+
12+
// Left-hand portion of the app, where component options are displayed
13+
const LeftContainer = (): JSX.Element => {
14+
return (
15+
<div className="column left" style={{ minWidth: '466px' }}>
16+
<Grid container spacing={8} direction="row" alignItems="center">
17+
<ComponentPanel />
18+
</Grid>
19+
</div>
20+
);
21+
}
22+
23+
export default LeftContainer;

src/containers/MainContainer.tsx

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
updateCode
1616
} from '../actions/actionCreators';
1717
import KonvaStage from '../components/main/KonvaStage';
18+
import MainCanvas from '../components/main/MainCanvasNew';
1819
import { PropsInt, ApplicationStateInt } from '../interfaces/Interfaces';
1920

2021
interface MainContPropsInt extends PropsInt {
@@ -31,7 +32,7 @@ interface MainContPropsInt extends PropsInt {
3132
deleteChild(obj: object): void;
3233
changeFocusComponent(arg: { title: string }): void;
3334
updateCode(arg: { componentId: number; code: string }): void;
34-
native: boolean;
35+
native: boolean;
3536
nativeImageElement: HTMLImageElement | null;
3637
}
3738

@@ -102,7 +103,6 @@ const mapStateToProps = (store: { workspace: ApplicationStateInt }) => ({
102103
});
103104

104105
class MainContainer extends Component<MainContPropsInt, StateInt> {
105-
106106
render() {
107107
//const { draggable, modal } = this.state; //this is being destructured but never read.
108108
const {
@@ -129,22 +129,7 @@ class MainContainer extends Component<MainContPropsInt, StateInt> {
129129
<div
130130
className="main" //ref={main} **no function, commenting out**
131131
>
132-
<KonvaStage
133-
image={image}
134-
scaleX={1}
135-
scaleY={1}
136-
// draggable={draggable} this is also from this local state but never read past this container
137-
components={components}
138-
handleTransform={handleTransformation}
139-
focusComponent={focusComponent}
140-
focusChild={focusChild}
141-
changeFocusChild={changeFocusChild}
142-
changeComponentFocusChild={changeComponentFocusChild}
143-
deleteChild={deleteChild}
144-
native={native}
145-
nativeImageElement={nativeImageElement}
146-
/* classes={classes} commented out because not used anywhere*/
147-
/>
132+
<MainCanvas />
148133
</div>
149134
<BottomPanel
150135
focusComponent={focusComponent}

src/context/context.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React from 'react';
2+
import { Context, ComponentBlueprint } from '../interfaces/InterfacesNew';
3+
4+
export const initialState: Context = {
5+
components: [],
6+
pages: [
7+
{
8+
pageId: 1,
9+
children: []
10+
}
11+
]
12+
};
13+
14+
export const CustomOptions: ComponentBlueprint[] = [
15+
{
16+
id: 0,
17+
category: 'CustomComponent',
18+
name: 'Tyler'
19+
},
20+
{
21+
id: 1,
22+
category: 'CustomComponent',
23+
name: 'Fredo'
24+
}
25+
];
26+
27+
export const HTMLOptions = [
28+
{
29+
id: 0,
30+
category: 'HTMLComponent',
31+
name: 'p'
32+
},
33+
{
34+
id: 1,
35+
category: 'HTMLComponent',
36+
name: 'h1'
37+
}
38+
];
39+
40+
export const stateContext = React.createContext([{}, () => {}]);

0 commit comments

Comments
 (0)