diff --git a/README.md b/README.md
index 315d1668b..cbabd22fa 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
### How to use
-- **Sign-in page**: Sign up for an account, sign in via Github, or just continue as a guest. Registered users enjoy additional project-saving functionality.
+- **Sign-in page**: Sign up for an account or just continue as a guest. Registered users enjoy additional project-saving functionality.
- **Tutorial**: Click ‘Tutorial’ from the Help tab’s dropdown menu (at the top left of the application) to view a tutorial.
- **Start a project (only after registration)**: Registered users can create a new project and select whether they want their project to be a Next.js, Gatsby.js, or classic React project. Also, registered users can save projects to return to them at a later time.
- **Add Components**: Create components on the right panel. Components can be associated with a route, or they can be used within other components.
@@ -34,6 +34,7 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
- **Create Instances on the Canvas**: Each component has its own canvas. Add an element to a component by dragging it onto the canvas. Div components are arbitrarily nestable and useful for complex layouts. Next.js and Gatsby.js projects have Link components to enable client-side navigation to other routes.
- **Component Tree**: Click on the Component Tree tab next to the Code Preview tab to view the component tree hierarchy.
- **Update Styling**: Select an element on the canvas to update its basic style attributes on the right panel. As you create new instances and add styling, watch as your code dynamically generates in the code preview in the bottom panel.
+- **Using State in Elements**: As of 9.0.0, you can now select an HTML element on the canvas and then navigate to the customization panel to click a button to pass a variable from state into your element's text or link field.
- **User Preference Features**: With the click of a button, toggle between light mode and dark mode, depending on your preference.
- **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 is mocked on the canvas.
- **Export project with Tests**: Click the "includes tests" checkbox while exporting to include pre-configured Webpack, Jest, and Typescript files along with tests for your project.
@@ -43,11 +44,17 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
- Modernized and cleaner UI, including enhanced dark mode
- Tutorial has been updated to reflect other modifications
- **New with version 8.0.0:**
+ **New with version 9.0.0:**
![CSSEditor](https://raw.githubusercontent.com/open-source-labs/ReacType/master/resources/export_tests_images/export-new.gif)
-### Features
+### 9.0.0 New Features
+- **React Router**: Drag-and-drop LinkTo and Router elements (located below the HTML elements list) to implement fully-functional React Router components into your application to dynamically and quickly render components in the live demo render and in your exported application.
+- **Global State Management**: For the first time in ReacType history, users can utilize
+- **Composite Data Structures in State**: State creation in ReacType can now handle composite data types, which includes arrays, objects, and any amount of nesting of composite data types within other composite data types (i.e. arrays of objects and objects with objects as values).
+- **Additional Improvements with Local State Management**:
+- **Annotations**:
+
- **OAuth via Github**: Sign up with your github accounts.
- **Live Render Demo**: Live render demo in React using Electron's sandbox environment. Updates in realtime to reflect canvas structure and customization options.
@@ -81,7 +88,7 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
- Delete Project: Command + Backspace
- Open Project: Command + o
-**Windows**:
+**Windows**:
- Export Project: Control + e
- Undo: Control + z
- Redo: Control + Shift + z
@@ -90,7 +97,7 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
- Delete HTML Tag on Canvas: Backspace
- Delete Project: Control + Backspace
- Open Project: Control + o
-
+
#### Contributors
[Alex Yu](https://www.linkedin.com/in/alexjihunyu/) [@buddhajjigae](https://github.com/buddhajjigae)
@@ -111,8 +118,12 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
[Chelsey Fewer](https://www.linkedin.com/in/chelsey-fewer/) [@chelseyeslehc](https://github.com/chelseyeslehc)
+[Chris Tang] (https://www.linkedin.com/in/chrisjtang/) [@chrisjtang](https://github.com/chrisjtang)
+
[Christian Padilla](https://linkedin.com/in/ChristianEdwardPadilla) [@ChristianEdwardPadilla](https://github.com/ChristianEdwardPadilla)
+[Crystal Lim] (https://linkedin.com/in/crystallim) [@crlim](https://github.com/crlim)
+
[Danial Reilley](https://linkedin.com/in/daniel-reilley)
[@dreille](https://github.com/dreille)
@@ -156,6 +167,8 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
[Philip Hua](https://www.linkedin.com/in/philip-minh-hua)
[@pmhua](https://github.com/pmhua)
+[Ron Fu] (https://www.linkedin.com/in/ronfu)[@rfvisuals] (https://github.com/rfvisuals)
+
[Sean Sadykoff](https://www.linkedin.com/in/sean-sadykoff/) [@sean1292](https://github.com/sean1292)
[Shana Hoehn](https://www.linkedin.com/in/shana-hoehn-70297b169/) [@slhoehn](https://github.com/slhoehn)
@@ -172,6 +185,8 @@ Download for [MacOS](https://github.com/team-reactype/ReacType/releases), [Windo
[Tyler Sullberg](https://www.linkedin.com/in/tyler-sullberg) [@tsully](https://github.com/tsully)
+[William Cheng] (https://www.linkedin.com/in/william-cheng-0723/) [@williamcheng12345](https://github.com/WilliamCheng12345)
+
[William Rittwage](https://www.linkedin.com/in/william-rittwage)
[@wbrittwage](https://github.com/wbrittwage)
diff --git a/app/electron/main.js b/app/electron/main.js
index 88cf5e2b4..3dfe330b4 100644
--- a/app/electron/main.js
+++ b/app/electron/main.js
@@ -73,7 +73,7 @@ async function createWindow() {
webPreferences: {
zoomFactor: 0.7,
// enable devtools when in development mode
- devTools: isDev,
+ devTools: true,
// crucial security feature - blocks rendering process from having access to node modules
nodeIntegration: false,
// web workers will not have access to node
diff --git a/app/src/components/bottom/UseStateModal.tsx b/app/src/components/bottom/UseStateModal.tsx
new file mode 100644
index 000000000..bbb367c0e
--- /dev/null
+++ b/app/src/components/bottom/UseStateModal.tsx
@@ -0,0 +1,87 @@
+import React, {useRef, useState, useContext, useEffect } from 'react';
+import Modal from '@material-ui/core/Modal';
+import StateContext from '../../context/context';
+import TableStateProps from '../right/TableStateProps';
+
+function UseStateModal({ updateAttributeWithState, attributeToChange, childId }) {
+ const [state, dispatch] = useContext(StateContext);
+ const [open, setOpen] = useState(false);
+ const [displayObject, setDisplayObject] = useState(null)
+ const [stateKey, setStateKey] = useState('');
+ const [statePropsId, setStatePropsId] = useState(-1);
+ const [componentProviderId, setComponentProviderId] = useState(1);
+
+ // make tabs to choose which component to get state from
+ const componentTabs = [];
+ for (let i = 0; i < state.components.length; i ++) {
+ componentTabs.push()
+ }
+
+ // table to choose state from
+ const body = (
+
+
+ Choose State Source
+
+
+
+
+ {componentTabs}
+
+
+ {
+ // if object or array => show sub table
+ if (table.row.type === "object") {
+ if (statePropsId < 0) setStatePropsId(table.row.id);
+ setStateKey(stateKey + table.row.key + '.');
+ setDisplayObject(table.row.value);
+ } else if (table.row.type === "array") {
+ if (statePropsId < 0) setStatePropsId(table.row.id);
+ setStateKey(stateKey + table.row.key)
+ setDisplayObject(table.row.value);
+ } else {
+ // if not object or array => update state
+ setDisplayObject(null);
+ updateAttributeWithState(attributeToChange, componentProviderId, statePropsId > 0 ? statePropsId : table.row.id, table.row, stateKey + table.row.key);
+ setStateKey('')
+ setStatePropsId(-1);
+ setOpen(false);
+ }
+ }}
+ deleteHandler={() => func()}
+ isThemeLight={true}
+ />
+
+
+
+ );
+
+ return (
+
+
+ {body}
+
+ );
+}
+
+export default UseStateModal;
diff --git a/app/src/components/left/DragDropPanel.tsx b/app/src/components/left/DragDropPanel.tsx
index ca8b1a446..37205458e 100644
--- a/app/src/components/left/DragDropPanel.tsx
+++ b/app/src/components/left/DragDropPanel.tsx
@@ -14,7 +14,7 @@ Central state contains all available HTML elements (stored in the HTMLTypes prop
initialState.tsx.
Hook state:
- -tag:
+ -tag:
*/
// Extracted the drag and drop functionality from HTMLPanel to make a modular component that can hang wherever the future designers may choose.
const DragDropPanel = (props): JSX.Element => {
@@ -37,25 +37,46 @@ const DragDropPanel = (props): JSX.Element => {
payload: id
});
};
-
+
// filter out separator so that it will not appear on the html panel
- const htmlTypesToRender = state.HTMLTypes.filter(type => type.name !== 'separator');
+ const htmlTypesToRender = state.HTMLTypes.filter(type => type.name !== 'separator' && type.name !== 'Route');
return (
diff --git a/app/src/components/main/AddRoute.tsx b/app/src/components/main/AddRoute.tsx
new file mode 100644
index 000000000..16ea9ea19
--- /dev/null
+++ b/app/src/components/main/AddRoute.tsx
@@ -0,0 +1,31 @@
+import { AddRoutes } from '../../interfaces/Interfaces'
+import React, {
+ useRef, useState, useContext, useEffect,
+} from 'react';
+import StateContext from '../../context/context';
+
+function AddRoute({
+ id,
+ name
+}: AddRoutes) {
+ const [state, dispatch] = useContext(StateContext);
+
+ const handleClick = (id) => {
+ dispatch({
+ type: 'ADD CHILD',
+ payload: {
+ type: 'HTML Element',
+ typeId: -1,
+ childId: id // this is the id of the parent to attach it to
+ }
+ });
+ }
+
+ return (
+
+
+
+ );
+}
+
+export default AddRoute;
diff --git a/app/src/components/main/Annotation.tsx b/app/src/components/main/Annotation.tsx
index c5404a9c3..66949adde 100644
--- a/app/src/components/main/Annotation.tsx
+++ b/app/src/components/main/Annotation.tsx
@@ -36,7 +36,7 @@ function Annotation({
};
/**
- * Handles when text exists in the textarea of the modal.
+ * Handles when text exists in the textarea of the modal.
* If text exists/does not exist, corresponding button changes colors.
* Sets hook value to what is contained in the textarea
*/
@@ -53,7 +53,7 @@ function Annotation({
}
/**
- * This handler will find the specific anno for the corresponding component on the canvas in the childrenArray -
+ * This handler will find the specific anno for the corresponding component on the canvas in the childrenArray -
* where the canvas components are placed
*/
const handleFindAnno = (array, id) => {
@@ -65,7 +65,7 @@ function Annotation({
} else if (currentElement.children.length > 0) {
// temp is to prevent a return of empty string since canvas element should always exist and allows the
// recursion to continue
- const temp = handleFindAnno(currentElement.children, id)
+ const temp = handleFindAnno(currentElement.children, id)
if (temp != '') {
return temp;
}
@@ -84,7 +84,7 @@ function Annotation({
}
handleAnnoChange(event);
}, [])
-
+
const body = (
Notes for: {name} ( {id} )
diff --git a/app/src/components/main/Canvas.tsx b/app/src/components/main/Canvas.tsx
index 13d9b12c8..844e34df0 100644
--- a/app/src/components/main/Canvas.tsx
+++ b/app/src/components/main/Canvas.tsx
@@ -16,7 +16,7 @@ function Canvas() {
const currentComponent: Component = state.components.find(
(elem: Component) => elem.id === state.canvasFocus.componentId
);
-
+
// changes focus of the canvas to a new component / child
const changeFocus = (componentId?: number, childId?: number | null) => {
dispatch({ type: 'CHANGE FOCUS', payload: { componentId, childId } });
@@ -24,10 +24,10 @@ function Canvas() {
// onClickHandler is responsible for changing the focused component and child component
function onClickHandler(event) {
event.stopPropagation();
- // note: a null value for the child id means that we are focusing on the top-level component rather than any child
+ // note: a null value for the child id means that we are focusing on the top-level component rather than any child
changeFocus(state.canvasFocus.componentId, null);
};
-
+
// stores a snapshot of state into the past array for UNDO. snapShotFunc is also invoked for nestable elements in DirectChildHTMLNestable.tsx
const snapShotFunc = () => {
// make a deep clone of state
diff --git a/app/src/components/main/DemoRender.tsx b/app/src/components/main/DemoRender.tsx
index 732b4cf65..9eacfdbc7 100644
--- a/app/src/components/main/DemoRender.tsx
+++ b/app/src/components/main/DemoRender.tsx
@@ -2,6 +2,7 @@
import React, {
useState, useCallback, useContext, useEffect,
} from 'react';
+import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Button from '@material-ui/core/Button';
import Box from '@material-ui/core/Box';
import StateContext from '../../context/context';
@@ -34,9 +35,13 @@ const DemoRender = (props): JSX.Element => {
if (elementType !== 'input' && elementType !== 'img' && element.children.length > 0) {
renderedChildren = componentBuilder(element.children);
}
+
if (elementType === 'input') componentsToRender.push();
else if (elementType === 'img') componentsToRender.push();
else if (elementType === 'a') componentsToRender.push({innerText});
+ else if (elementType === 'Switch') componentsToRender.push({renderedChildren});
+ else if (elementType === 'Route') componentsToRender.push({renderedChildren});
+ else if (elementType === 'LinkTo') componentsToRender.push({innerText});
else componentsToRender.push({innerText}{renderedChildren});
key += 1;
}
@@ -57,9 +62,12 @@ const DemoRender = (props): JSX.Element => {
return (
-
+
+
);
};
diff --git a/app/src/components/main/DirectChildComponent.tsx b/app/src/components/main/DirectChildComponent.tsx
index a3fc0833e..7d3c9aef4 100644
--- a/app/src/components/main/DirectChildComponent.tsx
+++ b/app/src/components/main/DirectChildComponent.tsx
@@ -9,9 +9,8 @@ import { ItemTypes } from '../../constants/ItemTypes';
import StateContext from '../../context/context';
import { combineStyles } from '../../helperFunctions/combineStyles';
import globalDefaultStyle from '../../public/styles/globalDefaultStyles';
-import renderChildren from '../../helperFunctions/renderChildren'
-function DirectChildComponent({ childId, type, typeId, style }: ChildElement) {
+function DirectChildComponent({ childId, type, typeId, style, name }: ChildElement) {
const [state, dispatch] = useContext(StateContext);
// find the top-level component corresponding to this instance of the component
@@ -64,13 +63,17 @@ function DirectChildComponent({ childId, type, typeId, style }: ChildElement) {
interactiveStyle
);
- return (
+
+ // Renders name and not children of subcomponents to clean up Canvas view when dragging components
+ // into the main canvas. To render html elements on canvas, import and invoke renderChildren
+ return (