mirror of
https://github.com/element-hq/element-web
synced 2024-11-22 09:15:41 +03:00
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:
parent
ed03a92712
commit
7925e7169a
10 changed files with 60 additions and 35 deletions
|
@ -118,7 +118,7 @@ textarea {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: $input-darker-fg-color;
|
color: $input-darker-fg-color;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid #c1c1c1;
|
border: 1px solid $dialog-close-fg-color;
|
||||||
// these things should probably not be defined
|
// these things should probably not be defined
|
||||||
// globally
|
// globally
|
||||||
margin: 9px;
|
margin: 9px;
|
||||||
|
@ -267,14 +267,18 @@ textarea {
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 40px 58px 36px 58px;
|
padding: 25px 30px 30px 30px;
|
||||||
width: 60%;
|
|
||||||
max-width: 704px;
|
max-width: 704px;
|
||||||
box-shadow: 2px 15px 30px 0 $dialog-shadow-color;
|
|
||||||
max-height: 80%;
|
max-height: 80%;
|
||||||
|
box-shadow: 2px 15px 30px 0 $dialog-shadow-color;
|
||||||
|
border-radius: 4px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_Dialog_fixedWidth {
|
||||||
|
min-width: 60vw;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_Dialog_staticWrapper .mx_Dialog {
|
.mx_Dialog_staticWrapper .mx_Dialog {
|
||||||
z-index: 4010;
|
z-index: 4010;
|
||||||
}
|
}
|
||||||
|
@ -317,13 +321,13 @@ textarea {
|
||||||
|
|
||||||
.mx_Dialog_header {
|
.mx_Dialog_header {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Dialog_title {
|
.mx_Dialog_title {
|
||||||
font-weight: bold;
|
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
line-height: 36px;
|
line-height: 36px;
|
||||||
color: $primary-fg-color;
|
color: $dialog-title-fg-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Dialog_header.mx_Dialog_headerWithButton > .mx_Dialog_title {
|
.mx_Dialog_header.mx_Dialog_headerWithButton > .mx_Dialog_title {
|
||||||
|
@ -338,13 +342,14 @@ textarea {
|
||||||
mask: url('$(res)/img/feather-customised/cancel.svg');
|
mask: url('$(res)/img/feather-customised/cancel.svg');
|
||||||
mask-repeat: no-repeat;
|
mask-repeat: no-repeat;
|
||||||
mask-position: center;
|
mask-position: center;
|
||||||
width: 36px;
|
mask-size: cover;
|
||||||
height: 36px;
|
width: 14px;
|
||||||
background-color: $primary-fg-color;
|
height: 14px;
|
||||||
|
background-color: $dialog-close-fg-color;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 20px;
|
top: 4px;
|
||||||
right: 20px;
|
right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Dialog_content {
|
.mx_Dialog_content {
|
||||||
|
@ -355,6 +360,7 @@ textarea {
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Dialog_buttons {
|
.mx_Dialog_buttons {
|
||||||
|
margin-top: 20px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,6 +376,10 @@ textarea {
|
||||||
background-color: $button-secondary-bg-color;
|
background-color: $button-secondary-bg-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_Dialog button:last-child {
|
||||||
|
margin-right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_Dialog button:hover, .mx_Dialog input[type="submit"]:hover {
|
.mx_Dialog button:hover, .mx_Dialog input[type="submit"]:hover {
|
||||||
@mixin mx_DialogButton_hover;
|
@mixin mx_DialogButton_hover;
|
||||||
}
|
}
|
||||||
|
@ -381,6 +391,7 @@ textarea {
|
||||||
.mx_Dialog button.mx_Dialog_primary, .mx_Dialog input[type="submit"].mx_Dialog_primary {
|
.mx_Dialog button.mx_Dialog_primary, .mx_Dialog input[type="submit"].mx_Dialog_primary {
|
||||||
color: $accent-fg-color;
|
color: $accent-fg-color;
|
||||||
background-color: $accent-color;
|
background-color: $accent-color;
|
||||||
|
min-width: 156px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger {
|
.mx_Dialog button.danger, .mx_Dialog input[type="submit"].danger {
|
||||||
|
|
|
@ -47,11 +47,11 @@
|
||||||
@import "./views/context_menus/_StatusMessageContextMenu.scss";
|
@import "./views/context_menus/_StatusMessageContextMenu.scss";
|
||||||
@import "./views/context_menus/_TagTileContextMenu.scss";
|
@import "./views/context_menus/_TagTileContextMenu.scss";
|
||||||
@import "./views/context_menus/_TopLeftMenu.scss";
|
@import "./views/context_menus/_TopLeftMenu.scss";
|
||||||
|
@import "./views/dialogs/_AddressPickerDialog.scss";
|
||||||
@import "./views/dialogs/_Analytics.scss";
|
@import "./views/dialogs/_Analytics.scss";
|
||||||
@import "./views/dialogs/_BugReportDialog.scss";
|
@import "./views/dialogs/_BugReportDialog.scss";
|
||||||
@import "./views/dialogs/_ChangelogDialog.scss";
|
@import "./views/dialogs/_ChangelogDialog.scss";
|
||||||
@import "./views/dialogs/_ChatCreateOrReuseChatDialog.scss";
|
@import "./views/dialogs/_ChatCreateOrReuseChatDialog.scss";
|
||||||
@import "./views/dialogs/_ChatInviteDialog.scss";
|
|
||||||
@import "./views/dialogs/_ConfirmUserActionDialog.scss";
|
@import "./views/dialogs/_ConfirmUserActionDialog.scss";
|
||||||
@import "./views/dialogs/_CreateGroupDialog.scss";
|
@import "./views/dialogs/_CreateGroupDialog.scss";
|
||||||
@import "./views/dialogs/_CreateRoomDialog.scss";
|
@import "./views/dialogs/_CreateRoomDialog.scss";
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2016 OpenMarket Ltd
|
Copyright 2016 OpenMarket Ltd
|
||||||
|
Copyright 2019 New Vector Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with 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 */
|
/* Using a textarea for this element, to circumvent autofill */
|
||||||
.mx_ChatInviteDialog_input,
|
.mx_AddressPickerDialog_input,
|
||||||
.mx_ChatInviteDialog_input:focus
|
.mx_AddressPickerDialog_input:focus
|
||||||
{
|
{
|
||||||
height: 26px;
|
height: 26px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -34,11 +35,11 @@ limitations under the License.
|
||||||
word-wrap: nowrap;
|
word-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_ChatInviteDialog .mx_Dialog_content {
|
.mx_AddressPickerDialog .mx_Dialog_content {
|
||||||
min-height: 50px
|
min-height: 50px
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_ChatInviteDialog_inputContainer {
|
.mx_AddressPickerDialog_inputContainer {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border: solid 1px $input-border-color;
|
border: solid 1px $input-border-color;
|
||||||
line-height: 36px;
|
line-height: 36px;
|
||||||
|
@ -51,19 +52,19 @@ limitations under the License.
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_ChatInviteDialog_error {
|
.mx_AddressPickerDialog_error {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
color: $warning-color;
|
color: $warning-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_ChatInviteDialog_cancel {
|
.mx_AddressPickerDialog_cancel {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 11px;
|
right: 11px;
|
||||||
top: 13px;
|
top: 13px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_ChatInviteDialog_cancel object {
|
.mx_AddressPickerDialog_cancel object {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ limitations under the License.
|
||||||
height: 80%;
|
height: 80%;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
padding-right: 0;
|
padding-right: 30px;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
|
|
||||||
.mx_TabbedView {
|
.mx_TabbedView {
|
||||||
|
@ -31,7 +31,7 @@ limitations under the License.
|
||||||
.mx_TabbedView .mx_SettingsTab {
|
.mx_TabbedView .mx_SettingsTab {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
min-width: 580px;
|
min-width: 580px;
|
||||||
padding-right: 130px;
|
padding-right: 100px;
|
||||||
|
|
||||||
// Put some padding on the bottom to avoid the settings tab from
|
// Put some padding on the bottom to avoid the settings tab from
|
||||||
// colliding harshly with the dialog when scrolled down.
|
// colliding harshly with the dialog when scrolled down.
|
||||||
|
|
|
@ -30,4 +30,6 @@ limitations under the License.
|
||||||
.mx_UploadConfirmDialog_imagePreview {
|
.mx_UploadConfirmDialog_imagePreview {
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid $dialog-close-fg-color;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,10 +106,10 @@ $avatar-bg-color: #ffffff;
|
||||||
|
|
||||||
$h3-color: #3d3b39;
|
$h3-color: #3d3b39;
|
||||||
|
|
||||||
$dialog-title-fg-color: #2e2f32;
|
$dialog-title-fg-color: #45474a;
|
||||||
$dialog-backdrop-color: rgba(46, 48, 51, 0.38);
|
$dialog-backdrop-color: rgba(46, 48, 51, 0.38);
|
||||||
$dialog-shadow-color: rgba(0, 0, 0, 0.48);
|
$dialog-shadow-color: rgba(0, 0, 0, 0.48);
|
||||||
$dialog-close-fg-color: #9fa9ba;
|
$dialog-close-fg-color: #c1c1c1;
|
||||||
|
|
||||||
$dialog-background-bg-color: #e9e9e9;
|
$dialog-background-bg-color: #e9e9e9;
|
||||||
$lightbox-background-bg-color: #000;
|
$lightbox-background-bg-color: #000;
|
||||||
|
|
|
@ -20,6 +20,7 @@ limitations under the License.
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const ReactDOM = require('react-dom');
|
const ReactDOM = require('react-dom');
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import classNames from 'classnames';
|
||||||
import Analytics from './Analytics';
|
import Analytics from './Analytics';
|
||||||
import sdk from './index';
|
import sdk from './index';
|
||||||
import dis from './dispatcher';
|
import dis from './dispatcher';
|
||||||
|
@ -158,7 +159,7 @@ class ModalManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
createDialog(Element, ...rest) {
|
createDialog(Element, ...rest) {
|
||||||
return this.createDialogAsync(new Promise(resolve => resolve(Element)), ...rest);
|
return this.createDialogAsync(Promise.resolve(Element), ...rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
createTrackedDialogAsync(analyticsAction, analyticsInfo, ...rest) {
|
createTrackedDialogAsync(analyticsAction, analyticsInfo, ...rest) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -566,7 +566,7 @@ module.exports = React.createClass({
|
||||||
rows="1"
|
rows="1"
|
||||||
id="textinput"
|
id="textinput"
|
||||||
ref="textinput"
|
ref="textinput"
|
||||||
className="mx_ChatInviteDialog_input"
|
className="mx_AddressPickerDialog_input"
|
||||||
onChange={this.onQueryChanged}
|
onChange={this.onQueryChanged}
|
||||||
placeholder={this.props.placeholder}
|
placeholder={this.props.placeholder}
|
||||||
defaultValue={this.props.value}
|
defaultValue={this.props.value}
|
||||||
|
@ -578,7 +578,7 @@ module.exports = React.createClass({
|
||||||
let addressSelector;
|
let addressSelector;
|
||||||
if (this.state.error) {
|
if (this.state.error) {
|
||||||
const validTypeDescriptions = this.props.validAddressTypes.map((t) => _t(addressTypeName[t]));
|
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.") }
|
{ _t("You have entered an invalid address.") }
|
||||||
<br />
|
<br />
|
||||||
{ _t("Try using one of the following valid address types: %(validTypesList)s.", {
|
{ _t("Try using one of the following valid address types: %(validTypesList)s.", {
|
||||||
|
@ -586,9 +586,9 @@ module.exports = React.createClass({
|
||||||
}) }
|
}) }
|
||||||
</div>;
|
</div>;
|
||||||
} else if (this.state.searchError) {
|
} 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) {
|
} 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 {
|
} else {
|
||||||
addressSelector = (
|
addressSelector = (
|
||||||
<AddressSelector ref={(ref) => {this.addressSelector = ref;}}
|
<AddressSelector ref={(ref) => {this.addressSelector = ref;}}
|
||||||
|
@ -601,13 +601,13 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseDialog className="mx_ChatInviteDialog" onKeyDown={this.onKeyDown}
|
<BaseDialog className="mx_AddressPickerDialog" onKeyDown={this.onKeyDown}
|
||||||
onFinished={this.props.onFinished} title={this.props.title}>
|
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>
|
<label htmlFor="textinput">{ this.props.description }</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content">
|
||||||
<div className="mx_ChatInviteDialog_inputContainer">{ query }</div>
|
<div className="mx_AddressPickerDialog_inputContainer">{ query }</div>
|
||||||
{ error }
|
{ error }
|
||||||
{ addressSelector }
|
{ addressSelector }
|
||||||
{ this.props.extraNode }
|
{ this.props.extraNode }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2017 Vector Creations Ltd
|
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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with 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
|
// CSS class to apply to dialog div
|
||||||
className: PropTypes.string,
|
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 for the dialog.
|
||||||
title: PropTypes.node.isRequired,
|
title: PropTypes.node.isRequired,
|
||||||
|
|
||||||
|
@ -72,6 +77,7 @@ export default React.createClass({
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
return {
|
return {
|
||||||
hasCancel: true,
|
hasCancel: true,
|
||||||
|
fixedWidth: true,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -113,7 +119,10 @@ export default React.createClass({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FocusTrap onKeyDown={this._onKeyDown}
|
<FocusTrap onKeyDown={this._onKeyDown}
|
||||||
className={this.props.className}
|
className={classNames({
|
||||||
|
[this.props.className]: true,
|
||||||
|
'mx_Dialog_fixedWidth': this.props.fixedWidth,
|
||||||
|
})}
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-labelledby='mx_BaseDialog_title'
|
aria-labelledby='mx_BaseDialog_title'
|
||||||
// This should point to a node describing the dialog.
|
// This should point to a node describing the dialog.
|
||||||
|
@ -131,8 +140,8 @@ export default React.createClass({
|
||||||
{ this.props.title }
|
{ this.props.title }
|
||||||
</div>
|
</div>
|
||||||
{ this.props.headerButton }
|
{ this.props.headerButton }
|
||||||
|
{ cancelButton }
|
||||||
</div>
|
</div>
|
||||||
{ cancelButton }
|
|
||||||
{ this.props.children }
|
{ this.props.children }
|
||||||
</FocusTrap>
|
</FocusTrap>
|
||||||
);
|
);
|
||||||
|
|
|
@ -87,6 +87,7 @@ export default class UploadConfirmDialog extends React.Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseDialog className='mx_UploadConfirmDialog'
|
<BaseDialog className='mx_UploadConfirmDialog'
|
||||||
|
fixedWidth={false}
|
||||||
onFinished={this._onCancelClick}
|
onFinished={this._onCancelClick}
|
||||||
title={title}
|
title={title}
|
||||||
contentId='mx_Dialog_content'
|
contentId='mx_Dialog_content'
|
||||||
|
|
Loading…
Reference in a new issue