Skip to content

Commit 47e3394

Browse files
authored
added prop-types for more safety with components (#9)
1 parent d214529 commit 47e3394

File tree

9 files changed

+99
-71
lines changed

9 files changed

+99
-71
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"dependencies": {
66
"@material-ui/core": "^4.3.2",
77
"@material-ui/icons": "^4.2.1",
8+
"prop-types": "^15.7.2",
89
"react": "^16.9.0",
910
"react-dom": "^16.9.0",
1011
"react-scripts": "3.1.1",

src/components/ErrorSnackbar.js

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from "react";
2+
import PropTypes from "prop-types";
23
import { withStyles, createStyles } from "@material-ui/core/styles";
34
import Snackbar from "@material-ui/core/Snackbar";
45
import SnackbarContent from "@material-ui/core/SnackbarContent";
@@ -19,26 +20,30 @@ const ErrorSnackbar = props => {
1920
autoHideDuration={5000}
2021
className={classes.snackbar}
2122
>
22-
{props.error && (
23-
<SnackbarContent
24-
className={classes.content}
25-
message={
26-
<span className={classes.message}>
27-
<ErrorIcon className={classes.errorIcon} />
28-
{props.error.toString()}
29-
</span>
30-
}
31-
action={[
32-
<IconButton key="close" color="inherit" onClick={props.onClose}>
33-
<CloseIcon className={classes.closeIcon} />
34-
</IconButton>
35-
]}
36-
/>
37-
)}
23+
<SnackbarContent
24+
className={classes.content}
25+
message={
26+
<span className={classes.message}>
27+
<ErrorIcon className={classes.errorIcon} />
28+
{props.error}
29+
</span>
30+
}
31+
action={[
32+
<IconButton key="close" color="inherit" onClick={props.onClose}>
33+
<CloseIcon className={classes.closeIcon} />
34+
</IconButton>
35+
]}
36+
/>
3837
</Snackbar>
3938
);
4039
};
4140

41+
ErrorSnackbar.propTypes = {
42+
error: PropTypes.string,
43+
onClose: PropTypes.func.isRequired,
44+
classes: PropTypes.objectOf(PropTypes.string)
45+
};
46+
4247
const styles = theme =>
4348
createStyles({
4449
snackbar: {

src/components/Main.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from "react";
2+
import PropTypes from "prop-types";
23
import { withStyles, createStyles } from "@material-ui/core/styles";
34
import Container from "@material-ui/core/Container";
45
import Grid from "@material-ui/core/Grid";
@@ -14,10 +15,8 @@ class Main extends React.Component {
1415
state = {
1516
cid: "",
1617
preferences: {
17-
one: "",
18-
two: "",
19-
three: "",
20-
codeStyle: "docco"
18+
username: "",
19+
codeStyle: "darcula"
2120
},
2221
justSaved: false,
2322
justLoaded: false,
@@ -53,7 +52,7 @@ class Main extends React.Component {
5352
try {
5453
preferences = await loadPreferences(cid);
5554
} catch (error) {
56-
this.setState({ error });
55+
this.setState({ error: error.toString() });
5756
return;
5857
}
5958
this.setState({
@@ -77,7 +76,7 @@ class Main extends React.Component {
7776
try {
7877
cid = await savePreferences(preferences);
7978
} catch (error) {
80-
this.setState({ error });
79+
this.setState({ error: error.toString() });
8180
return;
8281
}
8382
localStorage.setItem("preferenceCID", cid);
@@ -137,6 +136,10 @@ class Main extends React.Component {
137136
}
138137
}
139138

139+
Main.propTypes = {
140+
classes: PropTypes.objectOf(PropTypes.string).isRequired
141+
};
142+
140143
const styles = theme =>
141144
createStyles({
142145
container: {

src/components/PreferenceForm.js

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from "react";
2+
import PropTypes from "prop-types";
23
import { withStyles, createStyles } from "@material-ui/core/styles";
34
import Typography from "@material-ui/core/Typography";
45
import TextField from "@material-ui/core/TextField";
@@ -9,6 +10,8 @@ import Divider from "@material-ui/core/Divider";
910
import LoadIcon from "@material-ui/icons/Unarchive";
1011
import SaveIcon from "@material-ui/icons/Save";
1112
import SubmitButton from "./SubmitButton";
13+
import styleOptions from "../utils/styleOptions";
14+
import PrefPropType from "../utils/prefPropType";
1215

1316
class PreferenceForm extends React.Component {
1417
handleCIDChange = evt => {
@@ -46,23 +49,9 @@ class PreferenceForm extends React.Component {
4649
<Divider className={classes.divider} />
4750
<form onSubmit={this.props.onSave}>
4851
<TextField
49-
label="one"
50-
value={preferences.one}
51-
onChange={this.handlePrefChange("one")}
52-
fullWidth
53-
className={classes.input}
54-
/>
55-
<TextField
56-
label="two"
57-
value={preferences.two}
58-
onChange={this.handlePrefChange("two")}
59-
fullWidth
60-
className={classes.input}
61-
/>
62-
<TextField
63-
label="three"
64-
value={preferences.three}
65-
onChange={this.handlePrefChange("three")}
52+
label="username"
53+
value={preferences.username}
54+
onChange={this.handlePrefChange("username")}
6655
fullWidth
6756
className={classes.input}
6857
/>
@@ -91,22 +80,17 @@ class PreferenceForm extends React.Component {
9180
}
9281
}
9382

94-
const styleOptions = [
95-
"arduinoLight",
96-
"codepenEmbed",
97-
"darcula",
98-
"docco",
99-
"github",
100-
"googlecode",
101-
"hybrid",
102-
"monokaiSublime",
103-
"nord",
104-
"ocean",
105-
"pojoaque",
106-
"tomorrow",
107-
"tomorrowNight",
108-
"vs"
109-
];
83+
PreferenceForm.propTypes = {
84+
cid: PropTypes.string.isRequired,
85+
preferences: PrefPropType.isRequired,
86+
justSaved: PropTypes.bool.isRequired,
87+
justLoaded: PropTypes.bool.isRequired,
88+
onCIDChange: PropTypes.func.isRequired,
89+
onPrefChange: PropTypes.func.isRequired,
90+
onLoad: PropTypes.func.isRequired,
91+
onSave: PropTypes.func.isRequired,
92+
classes: PropTypes.objectOf(PropTypes.string)
93+
};
11094

11195
const styles = theme =>
11296
createStyles({

src/components/Preview.js

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import React from "react";
2+
import PropTypes from "prop-types";
23
import { withStyles, createStyles } from "@material-ui/core/styles";
34
import Typography from "@material-ui/core/Typography";
45
import { Light as SyntaxHighlighter } from "react-syntax-highlighter";
56
import js from "react-syntax-highlighter/dist/esm/languages/hljs/javascript";
67
import * as codeStyles from "react-syntax-highlighter/dist/esm/styles/hljs";
8+
import codeSample from "../utils/codeSample";
9+
import PrefPropType from "../utils/prefPropType";
710
SyntaxHighlighter.registerLanguage("javascript", js);
811

912
class Preview extends React.Component {
@@ -14,9 +17,7 @@ class Preview extends React.Component {
1417
<Typography variant="h5" className={classes.header}>
1518
Preview
1619
</Typography>
17-
<div>One: {preferences.one}</div>
18-
<div>Two: {preferences.two}</div>
19-
<div>Three: {preferences.three}</div>
20+
<div>One: {preferences.username}</div>
2021
<SyntaxHighlighter
2122
language="javascript"
2223
style={codeStyles[preferences.codeStyle]}
@@ -28,20 +29,10 @@ class Preview extends React.Component {
2829
}
2930
}
3031

31-
const codeSample = `
32-
export const ipfsIsWorking = async ipfs => {
33-
try {
34-
const id = await ipfs.id();
35-
if (id.id !== undefined && id.agentVersion !== undefined) {
36-
return true;
37-
} else {
38-
return false;
39-
}
40-
} catch (err) {
41-
return false;
42-
}
32+
Preview.propTypes = {
33+
preferences: PrefPropType,
34+
classes: PropTypes.objectOf(PropTypes.string)
4335
};
44-
`;
4536

4637
const styles = theme =>
4738
createStyles({

src/components/SubmitButton.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from "react";
2+
import PropTypes from "prop-types";
23
import { withStyles, createStyles } from "@material-ui/core/styles";
34
import Button from "@material-ui/core/Button";
45
import CheckIcon from "@material-ui/icons/Check";
@@ -22,6 +23,13 @@ const SubmitButton = props => {
2223
);
2324
};
2425

26+
SubmitButton.propTypes = {
27+
textNormal: PropTypes.string.isRequired,
28+
textSubmitted: PropTypes.string.isRequired,
29+
icon: PropTypes.element,
30+
submitted: PropTypes.bool
31+
};
32+
2533
const styles = theme =>
2634
createStyles({
2735
button: {

src/utils/codeSample.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export default `
2+
export const ipfsIsWorking = async ipfs => {
3+
try {
4+
const id = await ipfs.id();
5+
if (id.id !== undefined && id.agentVersion !== undefined) {
6+
return true;
7+
} else {
8+
return false;
9+
}
10+
} catch (err) {
11+
return false;
12+
}
13+
};
14+
`;

src/utils/prefPropType.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import PropTypes from "prop-types";
2+
3+
export default PropTypes.shape({
4+
username: PropTypes.string,
5+
codeStyle: PropTypes.string
6+
});

src/utils/styleOptions.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export default [
2+
"arduinoLight",
3+
"codepenEmbed",
4+
"darcula",
5+
"docco",
6+
"github",
7+
"googlecode",
8+
"hybrid",
9+
"monokaiSublime",
10+
"nord",
11+
"ocean",
12+
"pojoaque",
13+
"tomorrow",
14+
"tomorrowNight",
15+
"vs"
16+
];

0 commit comments

Comments
 (0)