Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ts-support): add typescript support #37

Merged
merged 4 commits into from
Dec 3, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13,917 changes: 13,917 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -5,6 +5,10 @@
"dependencies": {
"@material-ui/core": "^3.9.3",
"@material-ui/icons": "^3.0.2",
"@types/jest": "^24.0.12",
"@types/node": "^12.0.0",
"@types/react": "^16.8.17",
"@types/react-dom": "^16.8.4",
"classnames": "^2.2.6",
"highlight.js": "^9.15.8",
"lodash": "^4.17.11",
@@ -17,10 +21,12 @@
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"react-scripts": "^3.3.0",
"styled-components": "^4.3.1"
"styled-components": "^4.3.1",
"typescript": "^3.4.5"
},
"scripts": {
"start": "npm run build:markdown && react-scripts start",
"start:ts": "npm run build:markdown && REACT_APP_TS=true react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --passWithNoTests",
"eject": "react-scripts eject",
7 changes: 6 additions & 1 deletion src/FileReader.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
class FileReader {
readFile(fileLocation) {
let _fileLocation = fileLocation.replace('src', '.').replace('.js', '');

if (fileLocation.includes("exercise") && !fileLocation.includes("solution") && process.env.REACT_APP_TS === "true") {
_fileLocation = fileLocation.replace('src', '.').replace('.js', '_ts');
}

return import(`${_fileLocation}`)
.then(data => data.default);
}
}

export default new FileReader();
export default new FileReader();
29 changes: 29 additions & 0 deletions src/exercise/01-HelloWorld_ts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';

/**
*🏆
* The goal here is just to say Hello World.
* Follow the instruction inside return statement
*/
function HelloWorld(props) {
return (
/**
* ✏️
* Instead of returning null you would need to return a React element
* Use the React.createElement function to display a div
* and Hello World text inside the div
*/
null
);
}

/**
* 🚨 🚨 DO NOT DELETE OR CHANGE THIS.🚨 🚨
* This is how you would use your above component and
* the output of this code is displayed on the browser
*/
const Usage = (props) => {
return <HelloWorld />
}

export default Usage;
31 changes: 31 additions & 0 deletions src/exercise/02-IntroToJSX_ts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';

/**
*🏆
* The goal here is just to say Hello World.
* It is similar to previous exercise we did except instead of using
* React.createElement function we want to use JSX
*/
function HelloWorld(props){
return (
/**
* ✏️
* Instead of returning null you would need to return a React element
* Unlike earlier exercise where you returned React.createElement
* here you should use JSX to return a div with 'Hello World'
*/
null
);
}

/**
* 🚨 🚨 DO NOT DELETE OR CHANGE THIS.🚨 🚨
* This is how you would use your above component and
* the output of this code is displayed on the browser
*/
const Usage = (props) => {
return <HelloWorld />
}

export default Usage;

63 changes: 63 additions & 0 deletions src/exercise/03-PowerOfJSX_ts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';

/**
*🏆
* The goal here is to get you more familiar with JSX.
* You will use javascript code inside JSX to loop through object keys
* and render a div element for each element in that object
*/
function CompanyProfile(props) {
/**
* 💡 some variables to store mock data
* We will use these data to display the company profile information
*/
const stockTicker = 'APPL';
const companyProfileInfo = {
'Company Name': 'Apple Inc.',
'Price': 150,
'Exchange': "Nasdaq Global Select",
'Industry': "Computer Hardware",
'CEO': 'Timothy D. Cook'
}

return (
<div>
<div>Profile of: {/**✏️ display stock ticker here*/}</div>
<hr/>
<div>
{
/**
* ✏️
* This block is surrounded by curly braces {} so
* we can really execute any Javascript stuff here.
*
* Loop through the keys of companyProfileInfo
* object to render one div per key/value pair. The div should
* render key followed by a colon followed by value.
*
* 🧭 Object.keys(obj) can be used to loop through the object
* eg:
* const obj = { 'key1': 'value1', 'key2': 'value2'};
* Object.keys(obj) will return ['key1', 'key2']
* 🧭 You can use Array.map() to map any key to a div element
* eg:
* ['a', 'b', 'c'].map(d => <div>{d}</div>)
* 🧭 Remember to use curly braces inside the div to render
* any text content you want
*/
}
</div>
</div>
);
}

/**
* 🚨 🚨 DO NOT DELETE OR CHANGE THIS.🚨 🚨
* This is how you would use your above component and
* the output of this code is displayed on the browser
*/
const Usage = (props) => {
return <CompanyProfile />
}

export default Usage;
64 changes: 64 additions & 0 deletions src/exercise/04-Props_ts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react';

/**
* 🏆
* We are trying to make `CompanyProfile` component reusable
* Unlike previous exercise where we had `stockTicker` and `companyProfileInfo`
* hard-coded inside this component itself, we are now getting it as a props
*/
function CompanyProfile(props) {
/**
* Where do we get stockTicker and companyProfileInfo from?
* Well we get it as "props". The user of this component will
* pass the value for these two variables.
*/
const stockTicker = ''; //✏️ Instead of empty string we want to get this value from props
const companyProfileInfo = {}; //✏️ Instead of empty object we want to get this value from props
return (
<div>
<div>Profile of: {stockTicker}</div>
<hr />
<div>
{
Object.keys(companyProfileInfo)
.map((info, index) => {
return <div key={index}>{info} : {companyProfileInfo[info]}</div>
})
}
</div>
</div>
);
}

function FBCompanyProfile() {
/**
* We need to pass these data to the `CompanyProfile` component
* as the props
*/
const stockTicker = 'FB';
const companyProfileInfo = {
'Company Name': 'Facebook',
'Price': 150,
'Exchange': "Nasdaq Global Select",
'Industry': "Computer Software",
'CEO': 'Mark Zuckerberg'
}
/**
* ✏️ need to pass the props to the `CompanyProfile` component
* we need to pass `stockTicker` and `companyProfileInfo`
* */
return (
<CompanyProfile />
)
}

/**
* 🚨 🚨 DO NOT DELETE OR CHANGE THIS.🚨 🚨
* This is how you would use your above component and
* the output of this code is displayed on the browser
*/
const Usage = (props) => {
return <FBCompanyProfile />
}

export default Usage;
114 changes: 114 additions & 0 deletions src/exercise/05-State_ts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import React, { Component } from 'react';

/**
* 🏆
* Here we have a Counter component that display the current value of the counter
* It also has two buttons to increase ('+') or decrease('-') the counter.
* The counter value will be stored in the state.
* You need to update the state to add 1 to the counter when
* "+" is clicked and substract 1 to the current when "-" is clicked
*/
class Counter extends Component<any, any> {
constructor(props){
super(props);
/**
* ✏️
* Initialize a state here with initial value of counter set to 0
* this.state = { counter: defaultValue }
*/
this.state = {};

/**
* 💡
* We are binding the methods here, don't worry about this right now
* We will look at why we do this later in the tutorial
*/
this.increment = this.increment.bind(this);
this.decrement = this.decrement.bind(this);
}

/**
*💡
* This method will be called when the user clicks "+" button to increase the counter
*/
increment(){
/**
* ✏️
* You need to call setState here to update the `counter` state
* When user clicks the "+" we need to add 1 to the current state and
* set the state with the new value.
* We need to use value of current state to derive the new state,
* so it's better to use the updater function like
* this.setState(function(currentState) {
* return newState
* });
*/
}

/**
*💡
* This method will be called when the user clicks "-" button to decrease the counter
*/
decrement(){
/**
* ✏️
* You need to call setState here to update the `counter` state
* When user clicks the "-" we need to subtract 1 to the current state and
* set the state with the new value.
* We need to use value of current state to derive the new state,
* so it's better for us to use the updater function like
* this.setState(function(currentState) {
* return newState
* });
*/
}

render() {
return (
<div style={style.container}>
<div style={style.buttons}
onClick={this.decrement}>
-
</div>
<div style={style.counter}>
{this.state.counter}
</div>
<div style={style.buttons}
onClick={this.increment}>
+
</div>
</div>
);
}
}

/**
* 💡
* This is just some styling used
* You don't need to worry about this or change this
*/
const style = {
container: {
display: 'flex'
},
buttons: {
padding: `0px 7px 0px 7px`,
backgroundColor: 'grey',
cursor: 'pointer'
},
counter: {
padding: `0px 7px 0px 7px`
}
}


/**
* 🚨 🚨 DO NOT DELETE OR CHANGE THIS.🚨 🚨
* This is how you would use your above component and
* the output of this code is displayed on the browser
*/
const Usage = (props) => {
return <Counter />
};

export default Usage;
Loading
Oops, something went wrong.