Design tweaks to dialogs

Little bit of a mix of things in this one:
 * Support variable-width dialogs. Default is fixed-width as before,
   only UploadConformDialog is variable-width. Controlled by a prop
   to BaseDialog.
 * Fixes to the cancel 'x' - scale the mask image, tweak size & colour
 * Colour & boldness of dialog titles
 * Align the dialog title & cancel 'x'
 * Remove gap between dialog buttons & right hand side of dialog(!)
 * Round corners on dialogs
 * Add grey border on image preview in upload confirm dialog
 * and, squeezing in slightly randomly, finish the partially renamed
   ChatInviteDialog to AddressPickerDialog.
This commit is contained in:
David Baker 2019-04-03 16:27:45 +01:00
parent ed03a92712
commit 7925e7169a
10 changed files with 60 additions and 35 deletions

View file

@ -118,7 +118,7 @@ textarea {
background-color: transparent;
color: $input-darker-fg-color;
border-radius: 4px;
border: 1px solid #c1c1c1;
border: 1px solid $dialog-close-fg-color;
// these things should probably not be defined
// globally
margin: 9px;
@ -267,14 +267,18 @@ textarea {
font-weight: 300;
font-size: 15px;
position: relative;
padding: 40px 58px 36px 58px;
width: 60%;
padding: 25px 30px 30px 30px;
max-width: 704px;
box-shadow: 2px 15px 30px 0 $dialog-shadow-color;
max-height: 80%;
box-shadow: 2px 15px 30px 0 $dialog-shadow-color;
border-radius: 4px;
overflow-y: auto;
}
.mx_Dialog_fixedWidth {
min-width: 60vw;
}
.mx_Dialog_staticWrapper .mx_Dialog {
z-index: 4010;
}
@ -317,13 +321,13 @@ textarea {
.mx_Dialog_header {
position: relative;
margin-bottom: 20px;
}
.mx_Dialog_title {
font-weight: bold;
font-size: 22px;
line-height: 36px;
color: $primary-fg-color;
color: $dialog-title-fg-color;
}
.mx_Dialog_header.mx_Dialog_headerWithButton > .mx_Dialog_title {
@ -338,13 +342,14 @@ textarea {
mask: url('$(res)/img/feather-customised/cancel.svg');
mask-repeat: no-repeat;
mask-position: center;
width: 36px;
height: 36px;
background-color: $primary-fg-color;
mask-size: cover;
width: 14px;
height: 14px;
background-color: $dialog-close-fg-color;
cursor: pointer;
position: absolute;
top: 20px;
right: 20px;
top: 4px;
right: 0px;
}
.mx_Dialog_content {
@ -355,6 +360,7 @@ textarea {
}
.mx_Dialog_buttons {
margin-top: 20px;
text-align: right;
}
@ -370,6 +376,10 @@ textarea {
background-color: $button-secondary-bg-color;
}
.mx_Dialog button:last-child {
margin-right: 0px;
}
.mx_Dialog button:hover, .mx_Dialog input[type="submit"]:hover {
@mixin mx_DialogButton_hover;
}
@ -381,6 +391,7 @@ textarea {
.mx_Dialog button.mx_Dialog_primary, .mx_Dialog input[type="submit"].mx_Dialog_primary {
color: $accent-fg-color;
background-color: $accent-color;
min-width: 156px;
}
.mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger {

View file

@ -47,11 +47,11 @@
@import "./views/context_menus/_StatusMessageContextMenu.scss";
@import "./views/context_menus/_TagTileContextMenu.scss";
@import "./views/context_menus/_TopLeftMenu.scss";
@import "./views/dialogs/_AddressPickerDialog.scss";
@import "./views/dialogs/_Analytics.scss";
@import "./views/dialogs/_BugReportDialog.scss";
@import "./views/dialogs/_ChangelogDialog.scss";
@import "./views/dialogs/_ChatCreateOrReuseChatDialog.scss";
@import "./views/dialogs/_ChatInviteDialog.scss";
@import "./views/dialogs/_ConfirmUserActionDialog.scss";
@import "./views/dialogs/_CreateGroupDialog.scss";
@import "./views/dialogs/_CreateRoomDialog.scss";

View file

@ -1,5 +1,6 @@
/*
Copyright 2016 OpenMarket Ltd
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.
@ -15,8 +16,8 @@ limitations under the License.
*/
/* Using a textarea for this element, to circumvent autofill */
.mx_ChatInviteDialog_input,
.mx_ChatInviteDialog_input:focus
.mx_AddressPickerDialog_input,
.mx_AddressPickerDialog_input:focus
{
height: 26px;
font-size: 14px;
@ -34,11 +35,11 @@ limitations under the License.
word-wrap: nowrap;
}
.mx_ChatInviteDialog .mx_Dialog_content {
.mx_AddressPickerDialog .mx_Dialog_content {
min-height: 50px
}
.mx_ChatInviteDialog_inputContainer {
.mx_AddressPickerDialog_inputContainer {
border-radius: 3px;
border: solid 1px $input-border-color;
line-height: 36px;
@ -51,19 +52,19 @@ limitations under the License.
overflow-y: auto;
}
.mx_ChatInviteDialog_error {
.mx_AddressPickerDialog_error {
margin-top: 10px;
color: $warning-color;
}
.mx_ChatInviteDialog_cancel {
.mx_AddressPickerDialog_cancel {
position: absolute;
right: 11px;
top: 13px;
cursor: pointer;
}
.mx_ChatInviteDialog_cancel object {
.mx_AddressPickerDialog_cancel object {
pointer-events: none;
}

View file

@ -21,7 +21,7 @@ limitations under the License.
height: 80%;
border-radius: 4px;
padding-top: 0;
padding-right: 0;
padding-right: 30px;
padding-left: 0;
.mx_TabbedView {
@ -31,7 +31,7 @@ limitations under the License.
.mx_TabbedView .mx_SettingsTab {
box-sizing: border-box;
min-width: 580px;
padding-right: 130px;
padding-right: 100px;
// Put some padding on the bottom to avoid the settings tab from
// colliding harshly with the dialog when scrolled down.

View file

@ -30,4 +30,6 @@ limitations under the License.
.mx_UploadConfirmDialog_imagePreview {
max-height: 300px;
max-width: 100%;
border-radius: 4px;
border: 1px solid $dialog-close-fg-color;
}

View file

@ -106,10 +106,10 @@ $avatar-bg-color: #ffffff;
$h3-color: #3d3b39;
$dialog-title-fg-color: #2e2f32;
$dialog-title-fg-color: #45474a;
$dialog-backdrop-color: rgba(46, 48, 51, 0.38);
$dialog-shadow-color: rgba(0, 0, 0, 0.48);
$dialog-close-fg-color: #9fa9ba;
$dialog-close-fg-color: #c1c1c1;
$dialog-background-bg-color: #e9e9e9;
$lightbox-background-bg-color: #000;

View file

@ -20,6 +20,7 @@ limitations under the License.
const React = require('react');
const ReactDOM = require('react-dom');
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Analytics from './Analytics';
import sdk from './index';
import dis from './dispatcher';
@ -158,7 +159,7 @@ class ModalManager {
}
createDialog(Element, ...rest) {
return this.createDialogAsync(new Promise(resolve => resolve(Element)), ...rest);
return this.createDialogAsync(Promise.resolve(Element), ...rest);
}
createTrackedDialogAsync(analyticsAction, analyticsInfo, ...rest) {

View file

@ -1,6 +1,6 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017, 2018 New Vector Ltd
Copyright 2017, 2018, 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.
@ -566,7 +566,7 @@ module.exports = React.createClass({
rows="1"
id="textinput"
ref="textinput"
className="mx_ChatInviteDialog_input"
className="mx_AddressPickerDialog_input"
onChange={this.onQueryChanged}
placeholder={this.props.placeholder}
defaultValue={this.props.value}
@ -578,7 +578,7 @@ module.exports = React.createClass({
let addressSelector;
if (this.state.error) {
const validTypeDescriptions = this.props.validAddressTypes.map((t) => _t(addressTypeName[t]));
error = <div className="mx_ChatInviteDialog_error">
error = <div className="mx_AddressPickerDialog_error">
{ _t("You have entered an invalid address.") }
<br />
{ _t("Try using one of the following valid address types: %(validTypesList)s.", {
@ -586,9 +586,9 @@ module.exports = React.createClass({
}) }
</div>;
} else if (this.state.searchError) {
error = <div className="mx_ChatInviteDialog_error">{ this.state.searchError }</div>;
error = <div className="mx_AddressPickerDialog_error">{ this.state.searchError }</div>;
} else if (this.state.query.length > 0 && filteredSuggestedList.length === 0 && !this.state.busy) {
error = <div className="mx_ChatInviteDialog_error">{ _t("No results") }</div>;
error = <div className="mx_AddressPickerDialog_error">{ _t("No results") }</div>;
} else {
addressSelector = (
<AddressSelector ref={(ref) => {this.addressSelector = ref;}}
@ -601,13 +601,13 @@ module.exports = React.createClass({
}
return (
<BaseDialog className="mx_ChatInviteDialog" onKeyDown={this.onKeyDown}
<BaseDialog className="mx_AddressPickerDialog" onKeyDown={this.onKeyDown}
onFinished={this.props.onFinished} title={this.props.title}>
<div className="mx_ChatInviteDialog_label">
<div className="mx_AddressPickerDialog_label">
<label htmlFor="textinput">{ this.props.description }</label>
</div>
<div className="mx_Dialog_content">
<div className="mx_ChatInviteDialog_inputContainer">{ query }</div>
<div className="mx_AddressPickerDialog_inputContainer">{ query }</div>
{ error }
{ addressSelector }
{ this.props.extraNode }

View file

@ -1,6 +1,6 @@
/*
Copyright 2017 Vector Creations Ltd
Copyright 2018 New Vector Ltd
Copyright 2018, 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.
@ -55,6 +55,11 @@ export default React.createClass({
// CSS class to apply to dialog div
className: PropTypes.string,
// if true, dialog container is 60% of the viewport width. Otherwise,
// the container will have no fixed size, allowing its contents to
// determine its size. Default: true.
fixedWidth: PropTypes.bool,
// Title for the dialog.
title: PropTypes.node.isRequired,
@ -72,6 +77,7 @@ export default React.createClass({
getDefaultProps: function() {
return {
hasCancel: true,
fixedWidth: true,
};
},
@ -113,7 +119,10 @@ export default React.createClass({
return (
<FocusTrap onKeyDown={this._onKeyDown}
className={this.props.className}
className={classNames({
[this.props.className]: true,
'mx_Dialog_fixedWidth': this.props.fixedWidth,
})}
role="dialog"
aria-labelledby='mx_BaseDialog_title'
// This should point to a node describing the dialog.
@ -131,8 +140,8 @@ export default React.createClass({
{ this.props.title }
</div>
{ this.props.headerButton }
{ cancelButton }
</div>
{ cancelButton }
{ this.props.children }
</FocusTrap>
);

View file

@ -87,6 +87,7 @@ export default class UploadConfirmDialog extends React.Component {
return (
<BaseDialog className='mx_UploadConfirmDialog'
fixedWidth={false}
onFinished={this._onCancelClick}
title={title}
contentId='mx_Dialog_content'