Skip to content

Commit

Permalink
Merge pull request #177 from oslabs-beta/master
Browse files Browse the repository at this point in the history
Beta to OSLabs Launch Merge
  • Loading branch information
crlim committed Nov 24, 2021
2 parents 30fbc7c + f67c7e0 commit 639f1c7
Show file tree
Hide file tree
Showing 24 changed files with 862 additions and 249 deletions.
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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)

Expand Down Expand Up @@ -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)
Expand All @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion app/electron/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
87 changes: 87 additions & 0 deletions app/src/components/bottom/UseStateModal.tsx
Original file line number Diff line number Diff line change
@@ -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(<button
onClick={() => {
setComponentProviderId(i+1);
setDisplayObject(null);
setStateKey('');
}}>
{state.components[i].name}
</button>)
}

// table to choose state from
const body = (
<div className="useState-position">
<div className="useState-header">
<span>Choose State Source</span>
<button
style={{ margin: '5px 5px' ,padding: '1px', float: 'right' }}
onClick={() => {
setStateKey('');
setStatePropsId(-1);
setDisplayObject(null)
setOpen(false)}}
>
X
</button>
</div>
<div className="useState-window">
<div className="useState-dropdown">
{componentTabs}
</div>
<div className="useState-stateDisplay">
<TableStateProps
providerId = {componentProviderId}
canDeleteState = {false}
displayObject = {displayObject}
selectHandler={(table) => {
// 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}
/>
</div>
</div>
</div>
);

return (
<div>
<button className="useState-btn" onClick={() => setOpen(true)}>USE STATE</button>
<Modal open={open}>{body}</Modal>
</div>
);
}

export default UseStateModal;
47 changes: 34 additions & 13 deletions app/src/components/left/DragDropPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand All @@ -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 (
<div className="HTMLItems">
<div id="HTMLItemsTopHalf">
<Grid
id="HTMLItemsGrid"
>
{htmlTypesToRender.map(option => (
<HTMLItem
name={option.name}
key={`html-${option.name}`}
id={option.id}
Icon={option.icon}
handleDelete={handleDelete}
isThemeLight={isThemeLight}
/>
))}
<h3>HTML ELEMENTS</h3>
{htmlTypesToRender.map(option => {
if(option.id !== 17 && option.id !== 18) {
return (
<HTMLItem
name={option.name}
key={`html-${option.name}`}
id={option.id}
Icon={option.icon}
handleDelete={handleDelete}
isThemeLight={isThemeLight}
/>
);
}

})}
<h3>REACT ROUTER</h3>
{htmlTypesToRender.map(option => {
if(option.id === 17 || option.id === 18) {
return (
<HTMLItem
name={option.name}
key={`html-${option.name}`}
id={option.id}
Icon={option.icon}
handleDelete={handleDelete}
isThemeLight={isThemeLight}
/>
);
}
})}
</Grid>
</div>
</div>
Expand Down
10 changes: 5 additions & 5 deletions app/src/components/left/HTMLItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const useStyles = makeStyles({
darkThemeFontColor: {
color: '#fff'
}

});

const HTMLItem : React.FC<{
Expand All @@ -45,9 +45,9 @@ const HTMLItem : React.FC<{
handleDelete: (id: number) => void;
isThemeLight: boolean;
}> = ({ name, id, Icon, handleDelete, isThemeLight }) => {

const classes = useStyles();

const [modal, setModal] = useState(null);
const [{ isDragging }, drag] = useDrag({
item: {
Expand Down Expand Up @@ -122,11 +122,11 @@ const HTMLItem : React.FC<{
// updated the id's to reflect the new element types input and label
return ( // HTML Elements
<Grid item xs={5} key={`html-g${name}`}>
{ id <= 16 &&
{ id <= 18 &&
<div ref={drag} className={isThemeLight ? `${classes.HTMLPanelItem} ${classes.lightThemeFontColor}` : `${classes.HTMLPanelItem} ${classes.darkThemeFontColor}`} id="HTMLItem">
<h3>{name}</h3>
</div>}
{id > 16 &&
{id > 18 &&
<span id="customHTMLElement">
<div ref={drag} className={isThemeLight ? `${classes.HTMLPanelItem} ${classes.lightThemeFontColor}` : `${classes.HTMLPanelItem} ${classes.darkThemeFontColor}`} id="HTMLItem">
<h3>{name}</h3>
Expand Down
31 changes: 31 additions & 0 deletions app/src/components/main/AddRoute.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div style={{ padding: '1px', float: 'right' }}>
<button id={'routeBtn' + id} onClick={() => handleClick(id)}>+</button>
</div>
);
}

export default AddRoute;
8 changes: 4 additions & 4 deletions app/src/components/main/Annotation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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) => {
Expand All @@ -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;
}
Expand All @@ -84,7 +84,7 @@ function Annotation({
}
handleAnnoChange(event);
}, [])

const body = (
<div className='annotate-position'>
<span className='annotate-textarea-header'> Notes for: {name} ( {id} )</span>
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/main/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ 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 } });
};
// 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
Expand Down
Loading

0 comments on commit 639f1c7

Please sign in to comment.