Merge pull request #2269 from matrix-org/bwindels/roomlistpolish

Redesign: room list visual polish
pull/21833/head
Bruno Windels 2018-11-07 11:44:47 +00:00 committed by GitHub
commit 9e95a1402c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 255 additions and 203 deletions

View File

@ -18,6 +18,7 @@ limitations under the License.
1. for browsers that support native overlay auto-hiding scrollbars
*/
.mx_AutoHideScrollbar {
overflow-x: hidden;
overflow-y: auto;
-ms-overflow-style: -ms-autohiding-scrollbar;
}
@ -34,23 +35,20 @@ body.mx_scrollbar_overlay_noautohide .mx_AutoHideScrollbar:hover {
}
/*
3. as a last fallback, compensate for the scrollbar taking up space in the layout
by playing with the paddings. the default below will add a right padding
of the scrollbar width and clear that on hover.
this won't work well on classes that also need to set their padding,
so this needs to be overriden and adjust the padding with calc like so:
```
body.mx_scrollbar_nooverlay .componentClass.mx_AutoHideScrollbar_overflow:hover {
padding-right: calc(15px - var(--scrollbar-width)) !important;
}
```
by having giving the child element (.mx_AutoHideScrollbar_offset) a
negative right margin of the width of the scrollbar when the container
is overflowing. This is what Firefox ends up using. Overflow is detected
in javascript, and adds the mx_AutoHideScrollbar_overflow class to the container.
This only works in Firefox, which should be fine as this fallback is only needed there.
*/
body.mx_scrollbar_nooverlay .mx_AutoHideScrollbar {
box-sizing: border-box;
overflow-y: hidden;
padding-right: var(--scrollbar-width);
}
body.mx_scrollbar_nooverlay .mx_AutoHideScrollbar:hover {
overflow-y: auto;
padding-right: 0;
}
body.mx_scrollbar_nooverlay .mx_AutoHideScrollbar:hover.mx_AutoHideScrollbar_overflow > .mx_AutoHideScrollbar_offset {
margin-right: calc(-1 * var(--scrollbar-width));
}

View File

@ -22,99 +22,75 @@ limitations under the License.
}
.mx_RoomSubList_nonEmpty {
margin-bottom: 8px;
margin-bottom: 4px;
}
.mx_RoomSubList_labelContainer {
display: flex;
flex-direction: row;
align-items: center;
flex: 0 0 auto;
margin: 8px 19px 0 0;
margin: 0 16px;
height: 36px;
}
.mx_RoomSubList_label {
flex: 1;
position: relative;
cursor: pointer;
background-color: $secondary-accent-color;
display: flex;
align-items: center;
padding: 0 6px;
}
.mx_RoomSubList_label > span {
flex: 1 1 auto;
text-transform: uppercase;
color: $roomsublist-label-fg-color;
font-weight: 700;
font-size: 12px;
margin-left: 16px;
padding-left: 16px; /* gutter */
padding-right: 16px; /* gutter */
padding-top: 6px;
padding-bottom: 6px;
cursor: pointer;
background-color: $secondary-accent-color;
}
.mx_RoomSubList_label.mx_RoomSubList_fixed {
position: fixed;
top: 0;
z-index: 5;
/* pointer-events: none; */
margin-left: 8px;
}
.mx_RoomSubList_badge {
height: 18px;
border-radius: 9px;
flex: 0 0 auto;
border-radius: 8px;
color: $accent-fg-color;
font-weight: 600;
font-size: 12px;
vertical-align: middle;
line-height: 18px;
padding: 0 4px;
padding: 0 5px;
background-color: $accent-color;
}
.mx_RoomSubList_label .mx_RoomSubList_badge:hover {
filter: brightness($focus-brightness);
}
.mx_RoomSubList_addRoom, .mx_RoomSubList_badge {
margin: 5px;
margin-left: 7px;
}
.mx_RoomSubList_addRoom {
background-color: $roomheader-addroom-color;
color: $roomsublist-background;
border-radius: 9px;
text-align: center;
vertical-align: middle;
line-height: 18px;
font-weight: bold;
font-size: 18px;
width: 18px;
height: 18px;
background-image: url('../../img/icons-room-add.svg');
background-repeat: no-repeat;
background-position: center;
border-radius: 10px; // 16/2 + 2 padding
height: 16px;
flex: 0 0 16px;
background-clip: content-box;
}
.mx_RoomSubList_badgeHighlight {
background-color: $warning-color;
}
/* This is the bottom of the speech bubble */
.mx_RoomSubList_badgeHighlight:after {
content: "";
position: absolute;
display: block;
width: 0;
height: 0;
margin-left: 5px;
border-top: 5px solid $warning-color;
border-right: 7px solid transparent;
}
.mx_RoomSubList_chevron {
left: 0px;
pointer-events: none;
position: absolute;
top: 11px;
width: 9px;
height: 4px;
background-image: url('../../img/topleft-chevron.svg');
background-size: cover;
// the transition doesn't work as the chevron gets remounted
transition: rotateZ 0.2s ease-in;
background-repeat: no-repeat;
transition: transform 0.2s ease-in;
width: 10px;
height: 10px;
background-position: center;
margin-left: 2px;
}
.mx_RoomSubList_chevronDown {
@ -132,47 +108,26 @@ limitations under the License.
.mx_RoomSubList_scroll {
/* let rooms list grab all available space */
flex: 0 1 auto;
padding: 0 15px !important;
}
/*
for browsers that don't support overlay scrollbars,
subtract scrollbar width from right padding on hover when overflowing
so the content doesn't jump when showing the scrollbars
*/
body.mx_scrollbar_nooverlay .mx_RoomSubList_scroll.mx_AutoHideScrollbar_overflow:hover {
padding-right: calc(15px - var(--scrollbar-width)) !important;
padding: 0 8px;
}
.collapsed {
.mx_RoomSubList_label {
height: 17px;
width: 28px; /* collapsed LHS Panel width */
.mx_RoomSubList_scroll {
padding: 0;
}
.mx_RoomSubList_labelContainer {
width: 28px; /* collapsed LHS Panel width */
margin-right: 14px;
margin-left: 2px;
}
/* Hide the bottom of speech bubble */
.mx_RoomSubList_badgeHighlight:after {
display: none;
.mx_RoomSubList_addRoom {
margin-left: 3px;
margin-right: 28px;
}
.mx_RoomSubList_line {
display: none;
}
.mx_RoomSubList_moreBadge {
position: static;
margin-left: 16px;
margin-top: 2px;
}
.mx_RoomSubList_ellipsis {
height: 20px;
}
.mx_RoomSubList_more {
.mx_RoomSubList_label > span {
display: none;
}
}

View File

@ -21,11 +21,31 @@ limitations under the License.
cursor: pointer;
height: 40px;
margin: 0;
padding: 2px 12px;
padding: 0 8px 0 10px;
position: relative;
background-color: $secondary-accent-color;
}
.mx_RoomTile_menuButton {
display: none;
flex: 0 0 16px;
height: 16px;
background-image: url('../../img/icon_context.svg');
background-repeat: no-repeat;
background-position: center;
}
// toggle menuButton and badge on hover/menu displayed
.mx_LeftPanel_container:not(.collapsed) .mx_RoomTile:hover, .mx_RoomTile_menuDisplayed {
.mx_RoomTile_menuButton {
display: block;
}
.mx_RoomTile_badge {
display: none;
}
}
.mx_RoomTile_tooltip {
display: inline-block;
position: relative;
@ -63,14 +83,12 @@ limitations under the License.
text-overflow: ellipsis;
}
.mx_RoomTile_invite {
/* color: rgba(69, 69, 69, 0.5); */
}
.collapsed {
.mx_RoomTile {
margin: 2px;
padding: 2px 0 2px 12px;
margin: 0 2px;
padding: 0 2px;
position: relative;
justify-content: center;
}
.mx_RoomTile_name {
@ -78,57 +96,26 @@ limitations under the License.
}
.mx_RoomTile_badge {
display: block;
position: absolute;
height: 15px;
right: 8px;
top: 2px;
min-width: 12px;
right: 6px;
top: 0px;
border-radius: 16px;
padding: 0px 4px 0px 4px;
z-index: 3;
border: 0.18em solid $secondary-accent-color;
}
/* Hide the bottom of speech bubble */
.mx_RoomTile_highlight .mx_RoomTile_badge:after {
display: none;
.mx_RoomTile_menuButton {
display: none; //no design for this for now
}
}
/* This is the bottom of the speech bubble */
.mx_RoomTile_highlight .mx_RoomTile_badge:after {
content: "";
position: absolute;
display: block;
width: 0;
height: 0;
margin-left: 5px;
border-top: 5px solid $warning-color;
border-right: 7px solid transparent;
}
.mx_RoomTile_badge {
flex: 0 1 content;
min-width: 15px;
border-radius: 8px;
border-radius: 0.8em;
padding: 0 0.4em;
color: $accent-fg-color;
font-weight: 600;
font-size: 12px;
text-align: center;
padding-top: 1px;
padding-left: 4px;
padding-right: 4px;
}
.mx_RoomTile .mx_RoomTile_badge.mx_RoomTile_badgeButton,
.mx_RoomTile.mx_RoomTile_menuDisplayed .mx_RoomTile_badge {
letter-spacing: 0.1em;
opacity: 1;
}
.mx_RoomTile.mx_RoomTile_noBadges .mx_RoomTile_badge.mx_RoomTile_badgeButton,
.mx_RoomTile.mx_RoomTile_menuDisplayed.mx_RoomTile_noBadges .mx_RoomTile_badge {
background-color: $neutral-badge-color;
}
.mx_RoomTile_unreadNotify .mx_RoomTile_badge {
@ -170,10 +157,6 @@ limitations under the License.
background-color: $roomtile-focused-bg-color;
}
.mx_RoomTile .mx_RoomTile_name.mx_RoomTile_badgeShown {
width: 140px;
}
.mx_RoomTile_arrow {
position: absolute;
right: 0px;

View File

@ -1,23 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="svg4196" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 25 25"
style="enable-background:new 0 0 25 25;" xml:space="preserve">
<style type="text/css">
.st1{opacity:0.7;}
.st2{fill:none;stroke-linecap:round;}
</style>
<g id="icons_people" transform="translate(50.000000, 725.000000)">
<path id="Oval-1-Copy-7" fill="#76CFA6" d="M-37.5-700c6.9,0,12.5-5.6,12.5-12.5S-30.6-725-37.5-725S-50-719.4-50-712.5
S-44.4-700-37.5-700z"/>
<g id="text3879" transform="matrix(1.0243293,0,0,0.97624855,-24.996028,0.15844144)">
<g id="Group-3" transform="translate(14.4375,3.9375)" class="st1">
<path id="Line" class="st2" stroke="#ffffff" d="M-23.2-733.8h4.6"/>
<path id="path3142" class="st2" stroke="#ffffff" d="M-20.9-736.2v4.8"/>
</g>
<path id="path3002" fill="#ffffff" d="M-11.4-731.3l-0.5,2.6h2.2v1h-2.4l-0.7,3.3h-1.1l0.7-3.3
h-2.3l-0.6,3.3h-1.1l0.6-3.3h-2v-1h2.2l0.5-2.6H-18v-1h2.3l0.6-3.4h1.1l-0.6,3.4h2.4l0.7-3.4h1l-0.7,3.4h2v1H-11.4 M-15.3-728.7
h2.3l0.5-2.6h-2.3L-15.3-728.7"/>
</g>
</g>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="11.521363"
height="11.521363"
viewBox="0 0 11.521363 11.521363"
version="1.1"
id="svg4"
sodipodi:docname="icons-room-add.svg"
style="fill:none"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1586"
inkscape:window-height="988"
id="namedview6"
showgrid="false"
fit-margin-top="2"
fit-margin-left="2"
fit-margin-right="2"
fit-margin-bottom="2"
inkscape:zoom="29.5"
inkscape:cx="5.8284785"
inkscape:cy="5.7606831"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="0"
inkscape:current-layer="svg4" />
<path
d="m 5.7606819,2.7606819 v 6"
id="path2"
inkscape:connector-curvature="0"
style="stroke:#ffffff;stroke-width:1.5;stroke-linecap:round" />
<g
style="fill:none"
id="g876"
transform="translate(1.7606819,4.7606819)">
<path
id="path865"
d="M 7,1 H 1"
inkscape:connector-curvature="0"
style="stroke:#ffffff;stroke-width:1.5;stroke-linecap:round" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,17 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="10px" height="6px" viewBox="0 0 10 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>dropdown</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
<g id="matrix-my-stuff-no-lines-message-context-menu-smaller-icons" transform="translate(-203.000000, -25.000000)" stroke="#212121" stroke-width="1.3">
<g id="Group-3" transform="translate(128.000000, 15.000000)">
<g id="dropdown" transform="translate(76.000000, 11.000000)">
<path d="M0.5,0.5 L4.35868526,3.75422271" id="Line-5"></path>
<path d="M8.13193273,0.560421385 L4.35868526,3.75422271" id="Line-5-Copy"></path>
</g>
</g>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="9.946106"
height="5.5662179"
viewBox="0 0 9.946106 5.5662179"
version="1.1"
id="svg14"
sodipodi:docname="topleft-chevron.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata18">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>dropdown</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1277"
inkscape:window-height="653"
id="namedview16"
showgrid="false"
fit-margin-top="0.5"
fit-margin-left="0.5"
fit-margin-right="0.5"
fit-margin-bottom="0.5"
inkscape:zoom="35.2"
inkscape:cx="4.6570922"
inkscape:cy="2.9102278"
inkscape:window-x="459"
inkscape:window-y="90"
inkscape:window-maximized="0"
inkscape:current-layer="svg14" />
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title
id="title2">dropdown</title>
<desc
id="desc4">Created with Sketch.</desc>
<defs
id="defs6" />
<g
id="Page-1"
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round"
transform="translate(-0.3429078,-0.34400861)">
<g
id="matrix-my-stuff-no-lines-message-context-menu-smaller-icons"
transform="translate(-203,-25)"
style="stroke:#212121;stroke-width:1.29999995">
<g
id="Group-3"
transform="translate(128,15)">
<g
id="dropdown"
transform="translate(76,11)">
<path
d="M 0.5,0.5 4.3586853,3.7542227"
id="Line-5"
inkscape:connector-curvature="0" />
<path
d="M 8.1319327,0.56042139 4.3586853,3.7542227"
id="Line-5-Copy"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</svg>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1017 B

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -112,7 +112,9 @@ export default class AutoHideScrollbar extends React.Component {
ref={this._collectContainerRef}
className={["mx_AutoHideScrollbar", this.props.className].join(" ")}
>
{ this.props.children }
<div className="mx_AutoHideScrollbar_offset">
{ this.props.children }
</div>
</div>);
}
}

View File

@ -151,8 +151,7 @@ const LeftPanel = React.createClass({
}
} while (element && !(
classes.contains("mx_RoomTile") ||
classes.contains("mx_SearchBox_search") ||
classes.contains("mx_RoomSubList_ellipsis")));
classes.contains("mx_SearchBox_search")));
if (element) {
element.focus();

View File

@ -243,9 +243,8 @@ const RoomSubList = React.createClass({
const subListNotifCount = subListNotifications[0];
const subListNotifHighlight = subListNotifications[1];
let badge;
if (this.state.hidden) {
if (!this.props.collapsed) {
const badgeClasses = classNames({
'mx_RoomSubList_badge': true,
'mx_RoomSubList_badgeHighlight': subListNotifHighlight,
@ -285,9 +284,7 @@ const RoomSubList = React.createClass({
let addRoomButton;
if (this.props.onAddRoom) {
addRoomButton = (
<AccessibleButton onClick={ this.props.onAddRoom } className="mx_RoomSubList_addRoom">
+
</AccessibleButton>
<AccessibleButton onClick={ this.props.onAddRoom } className="mx_RoomSubList_addRoom" />
);
}
@ -307,7 +304,7 @@ const RoomSubList = React.createClass({
<div className="mx_RoomSubList_labelContainer" title={ title } ref="header">
<AccessibleButton onClick={ this.onClick } className="mx_RoomSubList_label" tabIndex={tabindex}>
{ chevron }
{ this.props.collapsed ? '' : this.props.label }
<span>{this.props.label}</span>
{ incomingCall }
</AccessibleButton>
{ badge }

View File

@ -220,7 +220,7 @@ module.exports = React.createClass({
this.setState( { badgeHover: false } );
},
onBadgeClicked: function(e) {
onOpenMenu: function(e) {
// Prevent the RoomTile onClick event firing as well
e.stopPropagation();
// Only allow non-guests to access the context menu
@ -276,19 +276,14 @@ module.exports = React.createClass({
if (name == undefined || name == null) name = '';
name = name.replace(":", ":\u200b"); // add a zero-width space to allow linewrapping after the colon
let badgeContent;
if (this.state.badgeHover || this.state.menuDisplayed) {
badgeContent = "\u00B7\u00B7\u00B7";
} else if (badges) {
let badge;
if (badges) {
const limitedCount = FormattingUtils.formatCount(notificationCount);
badgeContent = notificationCount ? limitedCount : '!';
} else {
badgeContent = '\u200B';
const badgeContent = notificationCount ? limitedCount : '!';
badge = <div className={badgeClasses}>{ badgeContent }</div>;
}
const badge = <div className={badgeClasses} onClick={this.onBadgeClicked}>{ badgeContent }</div>;
const EmojiText = sdk.getComponent('elements.EmojiText');
let label;
let tooltip;
@ -317,6 +312,11 @@ module.exports = React.createClass({
// incomingCallBox = <IncomingCallBox incomingCall={ this.props.incomingCall }/>;
//}
let contextMenuButton;
if (!MatrixClientPeg.get().isGuest()) {
contextMenuButton = <AccessibleButton className="mx_RoomTile_menuButton" onClick={this.onOpenMenu} />;
}
const RoomAvatar = sdk.getComponent('avatars.RoomAvatar');
let dmIndicator;
@ -338,6 +338,7 @@ module.exports = React.createClass({
</div>
</div>
{ label }
{ contextMenuButton }
{ badge }
{ /* { incomingCallBox } */ }
{ tooltip }