@@ -114,33 +114,37 @@ _./src/index.html_
114114npm 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
122124import * as React from " react" ;
123125import { 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" ;
125128import Card from " @material-ui/core/Card" ;
126129import CardHeader from " @material-ui/core/CardHeader" ;
127130import CardContent from " @material-ui/core/CardContent" ;
128131import TextField from " @material-ui/core/TextField" ;
129132import 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
142146const 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
262267const 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";
462523import Snackbar from " @material-ui/core/Snackbar" ;
463524import IconButton from " @material-ui/core/IconButton" ;
464525import 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
467529interface 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)) {
0 commit comments