Skip to content

Commit fab229a

Browse files
authored
Merge pull request #52 from brianjshan/final
Final
2 parents 84e2781 + 3e67ae0 commit fab229a

File tree

5 files changed

+85
-170
lines changed

5 files changed

+85
-170
lines changed

README.md

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,50 @@
11
<p align="center">
2-
<img width="50" src="url('./app/src/public/icons/png/256x256.png)">
2+
<img width="50" src=https://i.imgur.com/Z2aKWji.png?1>
33
<h1 align="center">ReacType </h1>
44
</p>
55
-->
66
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/team-reactype/ReacType/pulls)
77
![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
8-
![Release: 3.0](https://img.shields.io/badge/Release-3.0-orange)
8+
![Release: 4.0](https://img.shields.io/badge/Release-4.0-orange)
99

1010
**ReacType** is a visual prototyping tool for developers employing **React** component architecture alongside the comprehensive type checking of **TypeScript**.
1111
In other words, **you can draw prototypes and export React / Typescript code!**
1212

1313
**ReacType** allows the user to _visualize_ their application architecture dynamically, employing a _drag-and-drop canvas display_ and a _real-time component code preview_. The user can create components and drag _instances_ of these components, as well as HTML elements, onto the canvas. This architecture can then be _exported_ as TypeScript application files to be used as a starter template for any repository.
1414

15-
**New with version 3.0:**
15+
**New with version 4.0:**
1616

17-
- Export code as a [Next.js](https://nextjs.org/) project
18-
- Create nestable components/HTML elements using a drag-and-drop canvas
19-
- Add CSS to any element on the canvas
20-
- Components and HTML canvas elements are rendered in the canvas in the same way they'll be rendered in the exported project
21-
- View dynamically generated Next.js or classic React code as you build your project
22-
- Authenticate with Github or email
23-
- Save data for multiple projects in the cloud
24-
- Critical Electron security gaps resolved
17+
- View dynamically created components/HTML elements in the component tree
18+
- View Typescript syntax for React
19+
- Code preview is fully editable (make changes before exporting project)
20+
- Create custom HTML elements
21+
- Improved UI experience
22+
- Implemented a comprehensive tutorial page with images
2523

2624
Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windows](https://github.com/team-reactype/ReacType/releases/), [Linux](https://github.com/team-reactype/ReacType/releases/).
2725

2826
- **Mac users**: After opening the dmg and dragging ReacType into your Applications folder, ctrl+click the icon and select 'Open' from the context menu to run the app. This extra step is necessary since we don't have an Apple developer license yet.
2927

28+
- **Windows users**: Install the application by running ReacType Setup 4.0.0.exe.
29+
3030
- **Linux users**: Run the application as a super user in order to read and write files.
3131

32-
![Gif of adding](https://i.imgur.com/nOeuuU6.gif)
32+
![Gif of adding](https://i.imgur.com/Ioqkr00.gif)
3333

3434
### How to use
3535

36-
- **Log in:** Sign up through email/Github if you would like to save your projects to the cloud. Otherwise, select _Continue as Guest_
37-
- **Select project type:** By default, new projects will be Next.js projects, but you can toggle your project to be a normal React application by selecting "Classic React" in the bottom-right corner.
38-
- **Next.js** projects allow you to easily create routing between pages within ReacType and render content with static rendering.
39-
- **Classic React** projects are vanilla React. You can create multiple "root" components, but routing between these root components is enabled by default.
40-
- **Add components:** Add a new component in the left panel. If the _Page_ checkbox is selected, the component will become a page that can be routed to. For example, a page component named 'Home', the component's corresponding route will be '/Home'. [Learn more about Next.js routing](https://nextjs.org/docs/routing/introduction).
41-
- **Create instances of components/HTML elements:** Each component has its own canvas where you can see how any instances of nested components or HTML elements will render in production. To create an instance of a component or traditional HTML element in the canvas, simply drag it onto the canvas. The following elements have special properties when they're dragged onto the canvas:
42-
- **Page/root components:** Page/root components cannot be dragged into other components.
43-
- **Divs:** Divs are arbitrarily nestable.
44-
- **Navigation components:** Next.js projects have "Navigation components" which allow you to create links between your page components.
45-
- **Update CSS and delete instances:** Click on the component canvas or an instance to view/edit CSS attributes in the right panel. Updates made to the CSS will render in the canvas on _Save_.
46-
- **Save your project:** Select _Save Project_ to save a new project to the cloud. Once you've created a new project in the cloud, it will be autoamtically saved on each change. You can open any of your other saved projects by selecting _Open Project_.
47-
- **Export your project:** Select _Export Project_ to save your project locally. You will have the option of exporting either a fully functional application or only exporting the component files.
36+
- **Sign-in page**: Sign up for an account, authenticate via Github/Facebook, or just continue as a guest.
37+
- **Tutorial**: Click ‘Tutorial’ from the help tab’s drop-down menu of the help tab at the top left of the application to view a tutorial page.
38+
- **Start a project (only after authenticating)**: After you authenticate via Github/Facebook, create a new project, and select whether you want your project to be a Next.js or a classic React project. Also, save your project so that you can return to it at a later time.
39+
- **Add Components**: Create components on the left panel. Components can be associated with a route, or they can be used within other components.
40+
- **Delete Components**: Delete components after focusing on them from the right panel. Be careful when deleting components because all instances of the component will be deleted within the application/project.
41+
- **Add Custom Elements**: Create custom elements or add HTML elements that you are more familiar with into the application. Once the project is exported, the HTML tags generated in the code preview will function the way the label is supposed to work. You can create functionality for custom elements in a new file. The tutorial on HTML Elements explains more on how to do this.
42+
- **Delete Elements**: Delete elements by clicking on the ‘X’ button next to the element. Be careful when deleting elements because all element elements will be deleted within the application/project.
43+
- **Create instances on the canvas**: Each component has its canvas. Create an example of an element or HTML element by dragging it onto the canvas. Div components are arbitrarily nestable and useful for complex layouts. Next.js projects have Link components to enable client-side navigation to other routes.
44+
- **Component Tree**: Click on the component tree tab next to the code preview tab to view the component tree hierarchy.
45+
- **Update styling**: Click on an element on the canvas to update basic styling using the right functions. As you create new instances and add styling, watch as your code dynamically generates in the bottom panel.
46+
- **User preference features**: Select a theme for the code preview to your liking and change the application’s lighting.
47+
- **Export project**: Click the “Export Project’ button to export the project’s application files into a Typescript file. The exported project is fully functional with Webpack, Express server, routing, etc., and will match what’s mocked on the canvas.
4848

4949
#### Contributors
5050

@@ -54,18 +54,24 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
5454

5555
[Andrew Cho](https://www.linkedin.com/in/andrewjcho84/) [@andrewjcho84](https://github.com/andrewjcho84)
5656

57+
[Brian Han](https://www.linkedin.com/in/brianjisoohan/) [@brianjshan](https://github.com/brianjshan)
58+
5759
[Charles Finocchiaro](https://www.linkedin.com/in/charles-finocchiaro-62440040/) [@null267](https://github.com/null267)
5860

5961
[Chelsey Fewer](https://www.linkedin.com/in/chelsey-fewer/) [@chelseyeslehc](https://github.com/chelseyeslehc)
6062

6163
[Christian Padilla](https://linkedin.com/in/ChristianEdwardPadilla) [@ChristianEdwardPadilla](https://github.com/ChristianEdwardPadilla)
6264

65+
[Diego Vazquez](https://www.linkedin.com/in/diegovazquezny/) [@diegovazquezny](https://github.com/diegovazquezny)
66+
6367
[Eliot Nguyen](https://linkedin.com/in/ibeeliot) [@ibeeliot](https://github.com/ibeeliot)
6468

6569
[Fredo Chen](https://www.linkedin.com/in/fredochen/) [@fredosauce](https://github.com/fredosauce)
6670

6771
[Jesse Zuniga](https://linkedin.com/in/jesse-zuniga) [@jzuniga206](https://github.com/jzuniga206)
6872

73+
[Jin Soo Lim](https://www.linkedin.com/in/jin-soo-lim-3a567b1b3/) [@jinsoolim](https://github.com/jinsoolim)
74+
6975
[Mitchel Severe](https://www.linkedin.com/in/misevere/) [@mitchelsevere](https://github.com/mitchelsevere)
7076

7177
[Natalie Vick](https://www.linkedin.com/in/vicknatalie/) [@natattackvick](https://github.com/natattackvick)
@@ -78,6 +84,8 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
7884

7985
[Sophia Huttner](https://www.linkedin.com/in/sophia-huttner-68315975/) [@sophjean](https://github.com/sophjean)
8086

87+
[Stormi Hashimoto](https://www.linkedin.com/in/stormikph/) [@stormikph](https://github.com/stormikph)
88+
8189
[Tolga Mizrakci](https://linkedin.com/in/tolga-mizrakci) [@tolgamizrakci](https://github.com/tolgamizrakci)
8290

8391
[Tony Ito-Cole](https://linkedin.com/in/tony-ito-cole) [@tonyito](https://github.com/tonyito)

app/electron/menu.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ var MenuBuilder = function(mainWindow, appName) {
3232
}
3333
});
3434
if (process.env.NODE_ENV === 'development') {
35-
tutorial.loadURL(`http://localhost:8080/#/tutorial`);}
36-
else {
35+
tutorial.loadURL(`http://localhost:8080/#/tutorial`);
36+
} else {
3737
tutorial.loadURL(`${Protocol.scheme}://rse/index-prod.html#/tutorial`);
3838
}
3939
tutorial.show();

app/src/components/login/SignIn.tsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
RouteComponentProps
77
} from 'react-router-dom';
88
import { sessionIsCreated } from '../../helperFunctions/auth';
9-
import FacebookLogin from "react-facebook-login";
9+
import FacebookLogin from 'react-facebook-login';
1010
import Avatar from '@material-ui/core/Avatar';
1111
import Button from '@material-ui/core/Button';
1212
import CssBaseline from '@material-ui/core/CssBaseline';
@@ -36,7 +36,7 @@ const useStyles = makeStyles(theme => ({
3636
marginTop: theme.spacing(8),
3737
display: 'flex',
3838
flexDirection: 'column',
39-
alignItems: 'center',
39+
alignItems: 'center'
4040
},
4141
avatar: {
4242
margin: theme.spacing(1),
@@ -54,7 +54,7 @@ const useStyles = makeStyles(theme => ({
5454
'& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline': {
5555
borderColor: '#3EC1AC'
5656
}
57-
},
57+
}
5858
}));
5959

6060
const SignIn: React.FC<LoginInt & RouteComponentProps> = props => {
@@ -144,22 +144,25 @@ const SignIn: React.FC<LoginInt & RouteComponentProps> = props => {
144144

145145
const responseFacebook = response => {
146146
if (response.accessToken) {
147-
newUserIsCreated(response.email, response.email, randomPassword())
148-
.then(userCreated => {
147+
newUserIsCreated(response.email, response.email, randomPassword()).then(
148+
userCreated => {
149149
if (userCreated === 'Success') {
150150
props.history.push('/');
151151
} else {
152-
sessionIsCreated(response.email, randomPassword(), true)
153-
.then(loginStatus => {
152+
sessionIsCreated(response.email, randomPassword(), true).then(
153+
loginStatus => {
154154
if (loginStatus === 'Success') {
155155
props.history.push('/');
156156
}
157-
})
157+
}
158+
);
158159
}
159-
});
160-
}
161-
}
162-
const classBtn = 'MuiButtonBase-root MuiButton-root MuiButton-contained makeStyles-submit-4 MuiButton-fullWidth';
160+
}
161+
);
162+
}
163+
};
164+
const classBtn =
165+
'MuiButtonBase-root MuiButton-root MuiButton-contained makeStyles-submit-4 MuiButton-fullWidth';
163166
return (
164167
<Container component="main" maxWidth="xs">
165168
<CssBaseline />

app/src/components/main/Canvas.tsx

Lines changed: 23 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,36 @@
1-
import React, { useState, useContext } from 'react';
1+
import React, { useContext } from 'react';
22
import { useDrop, DropTargetMonitor } from 'react-dnd';
33
import { ItemTypes } from '../../constants/ItemTypes';
44
import StateContext from '../../context/context';
55
import { Component, DragItem } from '../../interfaces/Interfaces';
66
import { combineStyles } from '../../helperFunctions/combineStyles';
77
import renderChildren from '../../helperFunctions/renderChildren';
8-
import List from '@material-ui/core/List';
9-
import ListItem from '@material-ui/core/ListItem';
10-
import ListItemText from '@material-ui/core/ListItemText';
11-
import createModal from '../right/createModal';
12-
138
const findNestedChild = (curr, components) => {
149
components.forEach((comp, i) => {
1510
comp.children.forEach(child => {
16-
if (child.name === curr.name) {};
11+
if (child.name === curr.name) {
12+
}
1713
});
1814
if (comp.children.length !== 0) findNestedChild(curr, comp.children);
1915
});
20-
2116
};
22-
2317
function Canvas() {
24-
const [modal, setModal] = useState(null);
25-
2618
const [state, dispatch] = useContext(StateContext);
2719
// find the current component to render on the canvas
2820
const currentComponent: Component = state.components.find(
2921
(elem: Component) => elem.id === state.canvasFocus.componentId
3022
);
31-
23+
findNestedChild(currentComponent, state.components);
3224
// changes focus of the canvas to a new component / child
3325
const changeFocus = (componentId: number, childId: number | null) => {
3426
dispatch({ type: 'CHANGE FOCUS', payload: { componentId, childId } });
3527
};
36-
3728
// onClickHandler is responsible for changing the focused component and child component
3829
function onClickHandler(event) {
3930
event.stopPropagation();
4031
// note: a null value for the child id means that we are focusing on the top-level component rather than any child
4132
changeFocus(state.canvasFocus.componentId, null);
4233
}
43-
44-
const closeModal = () => setModal(null);
45-
46-
// creates modal that asks if user wants to clear workspace
47-
// if user clears their workspace, then their components are removed from state and the modal is closed
48-
const triedToNestIncorrectly = () => {
49-
// set modal options
50-
const children = (
51-
<List className="export-preference">
52-
<ListItem
53-
key={`gotIt${state.canvasFocus.componentId}`}
54-
button
55-
onClick={closeModal}
56-
style={{
57-
border: '1px solid #3f51b5',
58-
marginBottom: '2%',
59-
marginTop: '5%'
60-
}}
61-
>
62-
<ListItemText
63-
primary={'Got it'}
64-
style={{ textAlign: 'center' }}
65-
onClick={closeModal}
66-
/>
67-
</ListItem>
68-
</List>
69-
);
70-
71-
// create modal
72-
setModal(
73-
createModal({
74-
closeModal,
75-
children,
76-
message: 'Unable to nest component in another component that contains that component.',
77-
primBtnLabel: null,
78-
primBtnAction: null,
79-
secBtnAction: null,
80-
secBtnLabel: null,
81-
open: true
82-
})
83-
);
84-
};
85-
8634
// This hook will allow the user to drag items from the left panel on to the canvas
8735
const [{ isOver }, drop] = useDrop({
8836
accept: ItemTypes.INSTANCE,
@@ -91,69 +39,47 @@ function Canvas() {
9139
if (didDrop) {
9240
return;
9341
}
94-
95-
const runReducers = () => {
96-
if (item.newInstance) {
97-
dispatch({
98-
type: 'ADD CHILD',
99-
payload: {
100-
type: item.instanceType,
101-
typeId: item.instanceTypeId,
102-
childId: null
103-
}
104-
});
105-
}
106-
// if item is not a new instance, change position of element dragged inside div so that the div is the new parent
107-
else {
108-
dispatch({
109-
type: 'CHANGE POSITION',
110-
payload: {
111-
currentChildId: item.childId,
112-
newParentChildId: null
113-
}
114-
});
115-
}
42+
// if item dropped is going to be a new instance (i.e. it came from the left panel), then create a new child component
43+
if (item.newInstance) {
44+
dispatch({
45+
type: 'ADD CHILD',
46+
payload: {
47+
type: item.instanceType,
48+
typeId: item.instanceTypeId,
49+
childId: null
50+
}
51+
});
11652
}
117-
118-
const addingComponent = state.components.find(elem => elem.id === item.instanceTypeId);
119-
120-
if (item.instanceType === "HTML Element") {
121-
return runReducers();
122-
} else if (item.instanceType === 'Route Link') {
123-
return runReducers();
124-
} else if (checkChildren([addingComponent], currentComponent)) {
125-
triedToNestIncorrectly();
126-
return;
127-
} else {
128-
// if item dropped is going to be a new instance (i.e. it came from the left panel), then create a new child component
129-
return runReducers();
53+
// if item is not a new instance, change position of element dragged inside div so that the div is the new parent
54+
else {
55+
dispatch({
56+
type: 'CHANGE POSITION',
57+
payload: {
58+
currentChildId: item.childId,
59+
newParentChildId: null
60+
}
61+
});
13062
}
13163
},
13264
collect: monitor => ({
13365
isOver: !!monitor.isOver()
13466
})
13567
});
136-
13768
const defaultCanvasStyle = {
13869
width: '100%',
13970
minHeight: '100%',
14071
backgroundColor: isOver ? 'lightyellow' : 'white',
14172
border: '3px solid #01d46d',
14273
borderStyle: isOver ? 'dotted' : 'solid'
14374
};
144-
14575
// Combine the default styles of the canvas with the custom styles set by the user for that component
14676
// The render children function renders all direct children of a given component
14777
// Direct children are draggable/clickable
148-
149-
15078
const canvasStyle = combineStyles(defaultCanvasStyle, currentComponent.style);
15179
return (
15280
<div ref={drop} style={canvasStyle} onClick={onClickHandler}>
15381
{renderChildren(currentComponent.children)}
154-
{modal}
15582
</div>
15683
);
15784
}
158-
15985
export default Canvas;

0 commit comments

Comments
 (0)