Skip to content

Commit 2ef83ed

Browse files
authored
Merge pull request #180 from v-borrego/master
Adding material-ui hooks
2 parents ac12dbf + 6ea66ab commit 2ef83ed

File tree

11 files changed

+201
-122
lines changed

11 files changed

+201
-122
lines changed

hooks/13_LoginForm/Readme.md

Lines changed: 91 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -114,33 +114,37 @@ _./src/index.html_
114114
npm install @material-ui/core @material-ui/icons --save
115115
```
116116

117+
- However, we must be careful with the compatibility of certain versions of _typescript_ with the new _hooks_ of _material-ui_. For this example, we can install _typescript@3.3.3_ version. You can get more information about this issue in the following link https://github.com/mui-org/material-ui/issues/14018
118+
117119
- Now we could create a login form it could look something like:
118120

119121
_./src/pages/loginPage.tsx_
120122

121123
```javascript
122124
import * as React from "react";
123125
import { withRouter, RouteComponentProps } from "react-router-dom";
124-
import { withStyles, createStyles, WithStyles } from "@material-ui/core/styles";
126+
import makeStyles from "@material-ui/styles/makeStyles";
127+
import createStyles from "@material-ui/styles/createStyles";
125128
import Card from "@material-ui/core/Card";
126129
import CardHeader from "@material-ui/core/CardHeader";
127130
import CardContent from "@material-ui/core/CardContent";
128131
import TextField from "@material-ui/core/TextField";
129132
import Button from "@material-ui/core/Button";
130133

131-
// https://material-ui.com/guides/typescript/
132-
const styles = theme =>
134+
// https://material-ui.com/styles/api/#makestyles-styles-options-hook
135+
const useStyles = makeStyles(theme =>
133136
createStyles({
134137
card: {
135138
maxWidth: 400,
136139
margin: "0 auto"
137140
}
138-
});
141+
})
142+
);
139143

140-
interface Props extends RouteComponentProps, WithStyles<typeof styles> {}
144+
interface Props extends RouteComponentProps {}
141145

142146
const LoginPageInner = (props: Props) => {
143-
const { classes } = props;
147+
const classes = useStyles();
144148

145149
return (
146150
<Card className={classes.card}>
@@ -164,7 +168,7 @@ const LoginPageInner = (props: Props) => {
164168
);
165169
};
166170

167-
export const LoginPage = withStyles(styles)(withRouter<Props>(LoginPageInner));
171+
export const LoginPage = withRouter < Props > LoginPageInner;
168172
```
169173

170174
- This can be ok, but if we take a deeper look to this component, we could break down into two, one is the card itself the other the form dialog, so it should finally look like:
@@ -248,16 +252,17 @@ _./src/pages/login/loginPage.tsx_
248252
```diff
249253
// ...
250254

251-
// https://material-ui.com/guides/typescript/
252-
const styles = theme => createStyles({
253-
card: {
254-
maxWidth: 400,
255-
margin: '0 auto',
256-
},
257-
});
255+
// https://material-ui.com/styles/api/#makestyles-styles-options-hook
256+
const useStyles = makeStyles(theme =>
257+
createStyles({
258+
card: {
259+
maxWidth: 400,
260+
margin: "0 auto"
261+
}
262+
})
263+
);
258264

259-
interface Props extends RouteComponentProps, WithStyles<typeof styles> {
260-
}
265+
interface Props extends RouteComponentProps {}
261266

262267
const LoginPageInner = (props) => {
263268
const { classes } = props;
@@ -277,7 +282,7 @@ const LoginPageInner = (props) => {
277282
)
278283
}
279284

280-
export const LoginPage = withStyles(styles)(withRouter<Props>(LoginPageInner));
285+
export const LoginPage = withRouter<Props>(LoginPageInner);
281286
```
282287

283288
- Let's add the navigation on button clicked (later on we will check for user and pwd) _form.tsx_.
@@ -451,6 +456,62 @@ const LoginForm = (props: PropsForm) => {
451456
};
452457
```
453458

459+
- We will add material-ui classes to LoginForm component.
460+
461+
_./src/pages/loginPage.tsx_
462+
463+
```diff
464+
interface PropsForm {
465+
onLogin: () => void;
466+
onUpdateField: (name: string, value: any) => void;
467+
loginInfo : LoginEntity;
468+
}
469+
470+
+ // https://material-ui.com/styles/api/#makestyles-styles-options-hook
471+
+ const useFormStyles = makeStyles(theme =>
472+
+ createStyles({
473+
+ formContainer: {
474+
+ display: "flex",
475+
+ flexDirection: "column",
476+
+ justifyContent: "center"
477+
+ }
478+
+ })
479+
+ );
480+
481+
const LoginForm = (props: PropsForm) => {
482+
+ const classes = useFormStyles();
483+
const { onLogin, onUpdateField, loginInfo } = props;
484+
485+
// TODO: Enhacement move this outside the stateless component discuss why is a good idea
486+
const onTexFieldChange = (fieldId) => (e) => {
487+
onUpdateField(fieldId, e.target.value);
488+
}
489+
490+
return (
491+
- <div
492+
- style={{
493+
- display: "flex",
494+
- flexDirection: "column",
495+
- justifyContent: "center"
496+
- }}
497+
- >
498+
+ <div className={classes.formContainer}>
499+
<TextField label="Name" margin="normal"
500+
value={loginInfo.login}
501+
onChange={onTexFieldChange('login')}
502+
/>
503+
<TextField label="Password" type="password" margin="normal"
504+
value={loginInfo.password}
505+
onChange={onTexFieldChange('password')}
506+
/>
507+
<Button variant="contained" color="primary" onClick={onLogin}>
508+
Login
509+
</Button>
510+
</div>
511+
);
512+
};
513+
```
514+
454515
- Let's display a notification when the login validation fails.
455516

456517
- First we will create a simple notification component, base on _react material ui_ _snackbar_
@@ -462,23 +523,26 @@ import * as React from "react";
462523
import Snackbar from "@material-ui/core/Snackbar";
463524
import IconButton from "@material-ui/core/IconButton";
464525
import CloseIcon from "@material-ui/icons/Close";
465-
import { withStyles } from "@material-ui/core";
526+
import createStyles from "@material-ui/core/styles/createStyles";
527+
import makeStyles from "@material-ui/core/styles/makeStyles";
466528

467529
interface Props {
468-
classes?: any;
469530
message: string;
470531
show: boolean;
471532
onClose: () => void;
472533
}
473534

474-
const styles = theme => ({
475-
close: {
476-
padding: theme.spacing.unit / 2
477-
}
478-
});
535+
const useStyles = makeStyles(theme =>
536+
createStyles({
537+
close: {
538+
padding: theme.spacing(0.5)
539+
}
540+
})
541+
);
479542

480-
const NotificationComponentInner = (props: Props) => {
481-
const { classes, message, show, onClose } = props;
543+
export const NotificationComponent = (props: Props) => {
544+
const { message, show, onClose } = props;
545+
const classes = useStyles();
482546

483547
return (
484548
<Snackbar
@@ -507,10 +571,6 @@ const NotificationComponentInner = (props: Props) => {
507571
/>
508572
);
509573
};
510-
511-
export const NotificationComponent = withStyles(styles)(
512-
NotificationComponentInner
513-
);
514574
```
515575

516576
- Let's expose this common component via an _index_ file.
@@ -535,7 +595,7 @@ const LoginPageInner = (props: Props) => {
535595
createEmptyLogin()
536596
);
537597
+ const [showLoginFailedMsg, setShowLoginFailedMsg] = React.useState(false);
538-
const { classes } = props;
598+
const classes = useStyles();
539599

540600
const onLogin = () => {
541601
if (isValidLogin(loginInfo)) {

hooks/13_LoginForm/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
"webpack-dev-server": "^3.1.14"
3737
},
3838
"dependencies": {
39-
"@material-ui/core": "^3.9.3",
40-
"@material-ui/icons": "^3.0.2",
39+
"@material-ui/core": "^4.0.1",
40+
"@material-ui/icons": "^4.0.1",
4141
"react": "^16.8.2",
4242
"react-dom": "^16.8.2",
4343
"react-router-dom": "^4.3.1"

hooks/13_LoginForm/src/common/notification.tsx

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,26 @@ import * as React from "react";
22
import Snackbar from "@material-ui/core/Snackbar";
33
import IconButton from "@material-ui/core/IconButton";
44
import CloseIcon from "@material-ui/icons/Close";
5-
import { withStyles } from "@material-ui/core";
5+
import createStyles from "@material-ui/core/styles/createStyles";
6+
import makeStyles from "@material-ui/core/styles/makeStyles";
67

78
interface Props {
8-
classes?: any;
99
message: string;
1010
show: boolean;
1111
onClose: () => void;
1212
}
1313

14-
const styles = theme => ({
15-
close: {
16-
padding: theme.spacing.unit / 2
17-
}
18-
});
14+
const useStyles = makeStyles(theme =>
15+
createStyles({
16+
close: {
17+
padding: theme.spacing(0.5)
18+
}
19+
})
20+
);
1921

20-
const NotificationComponentInner = (props: Props) => {
21-
const { classes, message, show, onClose } = props;
22+
export const NotificationComponent = (props: Props) => {
23+
const classes = useStyles();
24+
const { message, show, onClose } = props;
2225

2326
return (
2427
<Snackbar
@@ -47,7 +50,3 @@ const NotificationComponentInner = (props: Props) => {
4750
/>
4851
);
4952
};
50-
51-
export const NotificationComponent = withStyles(styles)(
52-
NotificationComponentInner
53-
);

hooks/13_LoginForm/src/pages/loginPage.tsx

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as React from "react";
22
import { withRouter, RouteComponentProps } from "react-router-dom";
3-
import { withStyles, createStyles, WithStyles } from "@material-ui/core/styles";
3+
import makeStyles from "@material-ui/styles/makeStyles";
4+
import createStyles from "@material-ui/styles/createStyles";
45
import Card from "@material-ui/core/Card";
56
import CardHeader from "@material-ui/core/CardHeader";
67
import CardContent from "@material-ui/core/CardContent";
@@ -10,23 +11,24 @@ import { LoginEntity, createEmptyLogin } from "../model/login";
1011
import { isValidLogin } from "../api/login";
1112
import { NotificationComponent } from "../common";
1213

13-
// https://material-ui.com/guides/typescript/
14-
const styles = theme =>
14+
// https://material-ui.com/styles/api/#makestyles-styles-options-hook
15+
const useStyles = makeStyles(theme =>
1516
createStyles({
1617
card: {
1718
maxWidth: 400,
1819
margin: "0 auto"
1920
}
20-
});
21+
})
22+
);
2123

22-
interface Props extends RouteComponentProps, WithStyles<typeof styles> {}
24+
interface Props extends RouteComponentProps {}
2325

2426
const LoginPageInner = (props: Props) => {
2527
const [loginInfo, setLoginInfo] = React.useState<LoginEntity>(
2628
createEmptyLogin()
2729
);
2830
const [showLoginFailedMsg, setShowLoginFailedMsg] = React.useState(false);
29-
const { classes } = props;
31+
const classes = useStyles();
3032

3133
const onLogin = () => {
3234
if (isValidLogin(loginInfo)) {
@@ -64,15 +66,27 @@ const LoginPageInner = (props: Props) => {
6466
);
6567
};
6668

67-
export const LoginPage = withStyles(styles)(withRouter<Props>(LoginPageInner));
69+
export const LoginPage = withRouter<Props>(LoginPageInner);
6870

6971
interface PropsForm {
7072
onLogin: () => void;
7173
onUpdateField: (name: string, value: any) => void;
7274
loginInfo: LoginEntity;
7375
}
7476

77+
// https://material-ui.com/styles/api/#makestyles-styles-options-hook
78+
const useFormStyles = makeStyles(theme =>
79+
createStyles({
80+
formContainer: {
81+
display: "flex",
82+
flexDirection: "column",
83+
justifyContent: "center"
84+
}
85+
})
86+
);
87+
7588
const LoginForm = (props: PropsForm) => {
89+
const classes = useFormStyles();
7690
const { onLogin, onUpdateField, loginInfo } = props;
7791

7892
// TODO: Enhacement move this outside the stateless component discuss why is a good idea
@@ -81,13 +95,7 @@ const LoginForm = (props: PropsForm) => {
8195
};
8296

8397
return (
84-
<div
85-
style={{
86-
display: "flex",
87-
flexDirection: "column",
88-
justifyContent: "center"
89-
}}
90-
>
98+
<div className={classes.formContainer}>
9199
<TextField
92100
label="Name"
93101
margin="normal"

hooks/14_FormValidation/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
"webpack-dev-server": "^3.1.14"
3737
},
3838
"dependencies": {
39-
"@material-ui/core": "^3.9.2",
40-
"@material-ui/icons": "^3.0.2",
39+
"@material-ui/core": "^4.0.1",
40+
"@material-ui/icons": "^4.0.1",
4141
"lc-form-validation": "^2.0.0",
4242
"react": "^16.8.2",
4343
"react-dom": "^16.8.2",

0 commit comments

Comments
 (0)