Skip to content

Commit 7adeaf1

Browse files
authored
Merge pull request #6762 from marmelab/fix-login-theming
Ensure Login page is customizable through MUI theme
2 parents ac99133 + 965b7d4 commit 7adeaf1

File tree

1 file changed

+65
-56
lines changed

1 file changed

+65
-56
lines changed

packages/ra-ui-materialui/src/auth/Login.tsx

+65-56
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,52 @@ import { createMuiTheme } from '../layout';
2222
import DefaultNotification from '../layout/Notification';
2323
import DefaultLoginForm from './LoginForm';
2424

25+
/**
26+
* A standalone login page, to serve as authentication gate to the admin
27+
*
28+
* Expects the user to enter a login and a password, which will be checked
29+
* by the `authProvider.login()` method. Redirects to the root page (/)
30+
* upon success, otherwise displays an authentication error message.
31+
*
32+
* Copy and adapt this component to implement your own login logic
33+
* (e.g. to authenticate via email or facebook or anything else).
34+
*
35+
* @example
36+
* import MyLoginPage from './MyLoginPage';
37+
* const App = () => (
38+
* <Admin loginPage={MyLoginPage} authProvider={authProvider}>
39+
* ...
40+
* </Admin>
41+
* );
42+
*/
43+
const Login: React.FunctionComponent<LoginProps> = props => {
44+
const { theme, ...rest } = props;
45+
const muiTheme = useMemo(() => createMuiTheme(theme), [theme]);
46+
47+
return (
48+
<ThemeProvider theme={muiTheme}>
49+
<LoginView {...rest} />
50+
</ThemeProvider>
51+
);
52+
};
53+
54+
Login.propTypes = {
55+
backgroundImage: PropTypes.string,
56+
children: PropTypes.node,
57+
classes: PropTypes.object,
58+
className: PropTypes.string,
59+
theme: PropTypes.object,
60+
staticContext: PropTypes.object,
61+
};
62+
63+
Login.defaultProps = {
64+
theme: defaultTheme,
65+
children: <DefaultLoginForm />,
66+
notification: DefaultNotification,
67+
};
68+
69+
export default Login;
70+
2571
export interface LoginProps
2672
extends Omit<HtmlHTMLAttributes<HTMLDivElement>, 'title'> {
2773
backgroundImage?: string;
@@ -64,27 +110,8 @@ const useStyles = makeStyles(
64110
{ name: 'RaLogin' }
65111
);
66112

67-
/**
68-
* A standalone login page, to serve as authentication gate to the admin
69-
*
70-
* Expects the user to enter a login and a password, which will be checked
71-
* by the `authProvider.login()` method. Redirects to the root page (/)
72-
* upon success, otherwise displays an authentication error message.
73-
*
74-
* Copy and adapt this component to implement your own login logic
75-
* (e.g. to authenticate via email or facebook or anything else).
76-
*
77-
* @example
78-
* import MyLoginPage from './MyLoginPage';
79-
* const App = () => (
80-
* <Admin loginPage={MyLoginPage} authProvider={authProvider}>
81-
* ...
82-
* </Admin>
83-
* );
84-
*/
85-
const Login: React.FunctionComponent<LoginProps> = props => {
113+
const LoginView: React.FunctionComponent<Omit<LoginProps, 'theme'>> = props => {
86114
const {
87-
theme,
88115
title,
89116
classes: classesOverride,
90117
className,
@@ -95,9 +122,8 @@ const Login: React.FunctionComponent<LoginProps> = props => {
95122
...rest
96123
} = props;
97124
const containerRef = useRef<HTMLDivElement>();
125+
98126
const classes = useStyles(props);
99-
const muiTheme = useMemo(() => createMuiTheme(theme), [theme]);
100-
let backgroundImageLoaded = false;
101127
const checkAuth = useCheckAuth();
102128
const history = useHistory();
103129
useEffect(() => {
@@ -111,6 +137,8 @@ const Login: React.FunctionComponent<LoginProps> = props => {
111137
});
112138
}, [checkAuth, history]);
113139

140+
let backgroundImageLoaded = false;
141+
114142
const updateBackgroundImage = () => {
115143
if (!backgroundImageLoaded && containerRef.current) {
116144
containerRef.current.style.backgroundImage = `url(${backgroundImage})`;
@@ -134,39 +162,20 @@ const Login: React.FunctionComponent<LoginProps> = props => {
134162
});
135163

136164
return (
137-
<ThemeProvider theme={muiTheme}>
138-
<div
139-
className={classnames(classes.main, className)}
140-
{...rest}
141-
ref={containerRef}
142-
>
143-
<Card className={classes.card}>
144-
<div className={classes.avatar}>
145-
<Avatar className={classes.icon}>
146-
<LockIcon />
147-
</Avatar>
148-
</div>
149-
{children}
150-
</Card>
151-
{notification ? createElement(notification) : null}
152-
</div>
153-
</ThemeProvider>
165+
<div
166+
className={classnames(classes.main, className)}
167+
{...rest}
168+
ref={containerRef}
169+
>
170+
<Card className={classes.card}>
171+
<div className={classes.avatar}>
172+
<Avatar className={classes.icon}>
173+
<LockIcon />
174+
</Avatar>
175+
</div>
176+
{children}
177+
</Card>
178+
{notification ? createElement(notification) : null}
179+
</div>
154180
);
155181
};
156-
157-
Login.propTypes = {
158-
backgroundImage: PropTypes.string,
159-
children: PropTypes.node,
160-
classes: PropTypes.object,
161-
className: PropTypes.string,
162-
theme: PropTypes.object,
163-
staticContext: PropTypes.object,
164-
};
165-
166-
Login.defaultProps = {
167-
theme: defaultTheme,
168-
children: <DefaultLoginForm />,
169-
notification: DefaultNotification,
170-
};
171-
172-
export default Login;

0 commit comments

Comments
 (0)