Add modal look to authentication flows

This changes the auth screens to use the modal-like style of the redesign.

This does not attempt to style the actual body content of each screen.  Instead,
it covers the header area with logo, footer links, and overall modal container
only.
This commit is contained in:
J. Ryan Stinnett 2019-01-22 19:28:23 -06:00
parent 9d2bfdc0c0
commit 575cd1e37b
13 changed files with 113 additions and 42 deletions

View file

@ -23,6 +23,7 @@
@import "./structures/_UserSettings.scss"; @import "./structures/_UserSettings.scss";
@import "./structures/_ViewSource.scss"; @import "./structures/_ViewSource.scss";
@import "./structures/auth/_Login.scss"; @import "./structures/auth/_Login.scss";
@import "./views/auth/_AuthBody.scss";
@import "./views/auth/_AuthButtons.scss"; @import "./views/auth/_AuthButtons.scss";
@import "./views/auth/_AuthFooter.scss"; @import "./views/auth/_AuthFooter.scss";
@import "./views/auth/_AuthHeader.scss"; @import "./views/auth/_AuthHeader.scss";

View file

@ -0,0 +1,23 @@
/*
Copyright 2019 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_AuthBody {
width: 500px;
background-color: $authpage-body-bg-color;
border-radius: 0 4px 4px 0;
padding: 25px 60px;
box-sizing: border-box;
}

View file

@ -15,14 +15,14 @@ limitations under the License.
*/ */
.mx_AuthFooter { .mx_AuthFooter {
display: block;
text-align: center; text-align: center;
margin-top: 15px;
width: 100%; width: 100%;
font-size: 13px; font-size: 14px;
opacity: 0.8; opacity: 0.72;
margin: 20px 0;
} }
.mx_AuthFooter a:link { .mx_AuthFooter a:link, a:hover, a:visited {
color: $primary-fg-color; color: $accent-fg-color;
margin: 0 22px;
} }

View file

@ -14,12 +14,16 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
.mx_AuthHeader {
width: 206px;
padding: 25px 50px;
box-sizing: border-box;
}
.mx_AuthHeader_logo { .mx_AuthHeader_logo {
text-align: center; margin-top: 15px;
height: 150px;
margin-bottom: 45px;
} }
.mx_AuthHeader_logo img { .mx_AuthHeader_logo img {
max-height: 100% width: 100%;
} }

View file

@ -17,12 +17,10 @@ limitations under the License.
.mx_AuthPage { .mx_AuthPage {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
align-items: center; flex-direction: column;
justify-content: center;
overflow: auto; overflow: auto;
background-color: $authpage-bg-color;
} }
.mx_AuthPage h2 { .mx_AuthPage h2 {
@ -32,9 +30,11 @@ limitations under the License.
} }
.mx_AuthPage_modal { .mx_AuthPage_modal {
width: 300px; display: flex;
min-height: 450px; margin: 100px auto auto;
padding-top: 50px; border-radius: 4px;
padding-bottom: 50px; // Not currently supported in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1178765
margin: auto; backdrop-filter: blur(10px);
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.33);
background-color: $authpage-modal-bg-color;
} }

View file

@ -193,6 +193,10 @@ $room-warning-bg-color: #fff8e3;
$memberstatus-placeholder-color: $roomtile-name-color; $memberstatus-placeholder-color: $roomtile-name-color;
$authpage-bg-color: #2e3649;
$authpage-modal-bg-color: rgba(255, 255, 255, 0.59);
$authpage-body-bg-color: #ffffff;
/*** form elements ***/ /*** form elements ***/
// .mx_textinput is a container for a text input // .mx_textinput is a container for a text input

View file

@ -188,6 +188,10 @@ $room-warning-bg-color: #fff8e3;
$memberstatus-placeholder-color: $roomtile-name-color; $memberstatus-placeholder-color: $roomtile-name-color;
$authpage-bg-color: #2e3649;
$authpage-modal-bg-color: rgba(255, 255, 255, 0.59);
$authpage-body-bg-color: #ffffff;
// ***** Mixins! ***** // ***** Mixins! *****
@define-mixin mx_DialogButton { @define-mixin mx_DialogButton {

View file

@ -185,7 +185,7 @@ module.exports = React.createClass({
render: function() { render: function() {
const AuthPage = sdk.getComponent("auth.AuthPage"); const AuthPage = sdk.getComponent("auth.AuthPage");
const AuthHeader = sdk.getComponent("auth.AuthHeader"); const AuthHeader = sdk.getComponent("auth.AuthHeader");
const AuthFooter = sdk.getComponent("auth.AuthFooter"); const AuthBody = sdk.getComponent("auth.AuthBody");
const ServerConfig = sdk.getComponent("auth.ServerConfig"); const ServerConfig = sdk.getComponent("auth.ServerConfig");
const Spinner = sdk.getComponent("elements.Spinner"); const Spinner = sdk.getComponent("elements.Spinner");
@ -272,7 +272,6 @@ module.exports = React.createClass({
{ _t('Create an account') } { _t('Create an account') }
</a> </a>
<LanguageSelector /> <LanguageSelector />
<AuthFooter />
</div> </div>
</div> </div>
); );
@ -282,7 +281,9 @@ module.exports = React.createClass({
return ( return (
<AuthPage> <AuthPage>
<AuthHeader /> <AuthHeader />
{ resetPasswordJsx } <AuthBody>
{resetPasswordJsx}
</AuthBody>
</AuthPage> </AuthPage>
); );
}, },

View file

@ -517,7 +517,7 @@ module.exports = React.createClass({
const Loader = sdk.getComponent("elements.Spinner"); const Loader = sdk.getComponent("elements.Spinner");
const AuthPage = sdk.getComponent("auth.AuthPage"); const AuthPage = sdk.getComponent("auth.AuthPage");
const AuthHeader = sdk.getComponent("auth.AuthHeader"); const AuthHeader = sdk.getComponent("auth.AuthHeader");
const AuthFooter = sdk.getComponent("auth.AuthFooter"); const AuthBody = sdk.getComponent("auth.AuthBody");
const ServerConfig = sdk.getComponent("auth.ServerConfig"); const ServerConfig = sdk.getComponent("auth.ServerConfig");
const loader = this.state.busy ? <div className="mx_Login_loader"><Loader /></div> : null; const loader = this.state.busy ? <div className="mx_Login_loader"><Loader /></div> : null;
@ -560,7 +560,7 @@ module.exports = React.createClass({
return ( return (
<AuthPage> <AuthPage>
<AuthHeader /> <AuthHeader />
<div> <AuthBody>
{ header } { header }
{ errorTextSection } { errorTextSection }
{ this.componentForStep(this.state.currentFlow) } { this.componentForStep(this.state.currentFlow) }
@ -570,8 +570,7 @@ module.exports = React.createClass({
</a> </a>
{ loginAsGuestJsx } { loginAsGuestJsx }
<LanguageSelector /> <LanguageSelector />
<AuthFooter /> </AuthBody>
</div>
</AuthPage> </AuthPage>
); );
}, },

View file

@ -62,18 +62,21 @@ module.exports = React.createClass({
const ChangeAvatar = sdk.getComponent('settings.ChangeAvatar'); const ChangeAvatar = sdk.getComponent('settings.ChangeAvatar');
const AuthPage = sdk.getComponent('auth.AuthPage'); const AuthPage = sdk.getComponent('auth.AuthPage');
const AuthHeader = sdk.getComponent('auth.AuthHeader'); const AuthHeader = sdk.getComponent('auth.AuthHeader');
const AuthBody = sdk.getComponent("auth.AuthBody");
return ( return (
<AuthPage> <AuthPage>
<AuthHeader /> <AuthHeader />
<div className="mx_Login_profile"> <AuthBody>
{ _t('Set a display name:') } <div className="mx_Login_profile">
<ChangeDisplayName /> { _t('Set a display name:') }
{ _t('Upload an avatar:') } <ChangeDisplayName />
<ChangeAvatar { _t('Upload an avatar:') }
initialAvatarUrl={this.state.avatarUrl} /> <ChangeAvatar
<button onClick={this.props.onComplete}>{ _t('Continue') }</button> initialAvatarUrl={this.state.avatarUrl} />
{ this.state.errorString } <button onClick={this.props.onComplete}>{ _t('Continue') }</button>
</div> { this.state.errorString }
</div>
</AuthBody>
</AuthPage> </AuthPage>
); );
}, },

View file

@ -397,7 +397,7 @@ module.exports = React.createClass({
render: function() { render: function() {
const AuthHeader = sdk.getComponent('auth.AuthHeader'); const AuthHeader = sdk.getComponent('auth.AuthHeader');
const AuthFooter = sdk.getComponent('auth.AuthFooter'); const AuthBody = sdk.getComponent("auth.AuthBody");
const AuthPage = sdk.getComponent('auth.AuthPage'); const AuthPage = sdk.getComponent('auth.AuthPage');
const InteractiveAuth = sdk.getComponent('structures.InteractiveAuth'); const InteractiveAuth = sdk.getComponent('structures.InteractiveAuth');
const Spinner = sdk.getComponent("elements.Spinner"); const Spinner = sdk.getComponent("elements.Spinner");
@ -481,12 +481,13 @@ module.exports = React.createClass({
this.state.teamSelected.domain + "/icon.png" : this.state.teamSelected.domain + "/icon.png" :
null} null}
/> />
{ header } <AuthBody>
{ registerBody } { header }
{ signIn } { registerBody }
{ errorText } { signIn }
<LanguageSelector /> { errorText }
<AuthFooter /> <LanguageSelector />
</AuthBody>
</AuthPage> </AuthPage>
); );
}, },

View file

@ -0,0 +1,27 @@
/*
Copyright 2019 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
import React from 'react';
export default class AuthBody extends React.PureComponent {
render() {
return <div className="mx_AuthBody">
{ this.props.children }
</div>;
}
}

View file

@ -18,16 +18,20 @@ limitations under the License.
'use strict'; 'use strict';
const React = require('react'); const React = require('react');
import sdk from '../../../index';
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'AuthPage', displayName: 'AuthPage',
render: function() { render: function() {
const AuthFooter = sdk.getComponent('auth.AuthFooter');
return ( return (
<div className="mx_AuthPage"> <div className="mx_AuthPage">
<div className="mx_AuthPage_modal"> <div className="mx_AuthPage_modal">
{ this.props.children } { this.props.children }
</div> </div>
<AuthFooter />
</div> </div>
); );
}, },