Improve design of the rich text editor (#9533)

New design for rich text composer
This commit is contained in:
Florian Duros 2022-11-04 16:36:50 +01:00 committed by GitHub
parent 9101b42de8
commit 5ca9accce2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 668 additions and 270 deletions

View file

@ -260,6 +260,7 @@
@import "./views/rooms/_AuxPanel.pcss";
@import "./views/rooms/_BasicMessageComposer.pcss";
@import "./views/rooms/_E2EIcon.pcss";
@import "./views/rooms/_EmojiButton.pcss";
@import "./views/rooms/_EditMessageComposer.pcss";
@import "./views/rooms/_EntityTile.pcss";
@import "./views/rooms/_EventBubbleTile.pcss";

View file

@ -0,0 +1,35 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
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.
*/
@import "./_MessageComposerButton.pcss";
.mx_EmojiButton {
@mixin composerButton 50%,$accent;
}
.mx_EmojiButton_highlight {
@mixin composerButtonHighLight;
}
.mx_EmojiButton_icon::before {
mask-image: url('$(res)/img/element-icons/room/composer/emoji.svg');
}
.mx_MessageComposer_wysiwyg {
.mx_EmojiButton {
@mixin composerButton 5px,$tertiary-content;
}
}

View file

@ -15,6 +15,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
@import "./_MessageComposerButton.pcss";
.mx_MessageComposer_wrapper {
vertical-align: middle;
margin: auto;
@ -59,6 +61,12 @@ limitations under the License.
width: 100%;
}
.mx_MessageComposer_actions {
display: flex;
align-items: center;
gap: 6px;
}
.mx_MessageComposer .mx_MessageComposer_avatar {
position: absolute;
left: 26px;
@ -171,53 +179,16 @@ limitations under the License.
}
.mx_MessageComposer_button_highlight {
background: rgba($accent, 0.25);
/* make the icon the accent color too */
&::before {
background-color: $accent !important;
}
@mixin composerButtonHighLight;
}
.mx_MessageComposer_button {
--size: 26px;
position: relative;
cursor: pointer;
height: var(--size);
line-height: var(--size);
width: auto;
padding-left: var(--size);
border-radius: 50%;
margin-right: 6px;
@mixin composerButton 50%,$accent;
&:last-child {
margin-right: auto;
}
&::before {
content: '';
position: absolute;
top: 3px;
left: 3px;
height: 20px;
width: 20px;
background-color: $icon-button-color;
mask-repeat: no-repeat;
mask-size: contain;
mask-position: center;
}
&::after {
content: '';
position: absolute;
left: 0;
top: 0;
z-index: 0;
width: var(--size);
height: var(--size);
border-radius: 50%;
}
&:hover,
&.mx_MessageComposer_closeButtonMenu {
&::after {
background: rgba($accent, 0.1);
@ -232,15 +203,43 @@ limitations under the License.
background-color: $alert;
}
}
/*
The wysisyg composer increase the size of the MessageComposer. We temporary move the buttons
Soon the dom structure of the MessageComposer will change with the next evolution of the wysiwyg composer
and this workaround will disappear
*/
.mx_MessageComposer_wysiwyg {
.mx_MessageComposer_e2eIcon.mx_E2EIcon,.mx_MessageComposer_button, .mx_MessageComposer_sendMessage {
margin-top: 28px;
.mx_MessageComposer_wrapper {
padding-left: 16px;
margin-top: 6px;
margin-bottom: 12px;
}
.mx_MessageComposer_row {
align-items: flex-end;
}
.mx_MessageComposer_actions {
/* Height of the composer editor */
height: 40px;
}
.mx_MediaBody {
padding-top: 4px;
padding-bottom: 4px;
}
.mx_MessageComposer_button {
@mixin composerButton 5px,$tertiary-content;
&.mx_MessageComposer_closeButtonMenu {
&::after {
background: rgba($accent, 0.1);
}
&::before {
background-color: $accent;
}
}
&.mx_MessageComposer_hangup:not(.mx_AccessibleButton_disabled)::before {
background-color: $alert;
}
}
}
@ -260,10 +259,6 @@ limitations under the License.
mask-image: url('$(res)/img/element-icons/live.svg');
}
.mx_MessageComposer_emoji::before {
mask-image: url('$(res)/img/element-icons/room/composer/emoji.svg');
}
.mx_MessageComposer_plain_text::before {
mask-image: url('$(res)/img/element-icons/room/composer/plain_text.svg');
}

View file

@ -0,0 +1,68 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
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.
*/
@define-mixin composerButtonHighLight {
background: rgba($accent, 0.25);
/* make the icon the accent color too */
&::before {
background-color: $accent !important;
}
}
@define-mixin composerButton $border-radius,$hover-color {
--size: 26px;
position: relative;
cursor: pointer;
height: var(--size);
line-height: var(--size);
width: auto;
padding-left: var(--size);
border-radius: $border-radius;
&::before {
content: '';
position: absolute;
top: 3px;
left: 3px;
height: 20px;
width: 20px;
background-color: $icon-button-color;
mask-repeat: no-repeat;
mask-size: contain;
mask-position: center;
}
&::after {
content: '';
position: absolute;
left: 0;
top: 0;
z-index: 0;
width: var(--size);
height: var(--size);
border-radius: $border-radius;
}
&:hover {
&::after {
background: rgba($hover-color, 0.1);
}
&::before {
background-color: $hover-color;
}
}
}

View file

@ -20,7 +20,7 @@ limitations under the License.
height: 28px;
border: 2px solid $voice-record-stop-border-color;
border-radius: 32px;
margin-right: 8px; /* between us and the waveform component */
margin-right: 2px; /* between us and the waveform component */
position: relative;
&::after {
@ -39,7 +39,7 @@ limitations under the License.
width: 24px;
height: 24px;
vertical-align: middle;
margin-right: 8px; /* distance from left edge of waveform container (container has some margin too) */
margin-right: 2px; /* distance from left edge of waveform container (container has some margin too) */
background-color: $voice-record-icon-color;
mask-repeat: no-repeat;
mask-size: contain;
@ -69,7 +69,7 @@ limitations under the License.
height: 32px;
margin: 6px; /* force the composer area to put a gutter around us */
margin-right: 12px; /* isolate from stop/send button */
margin-right: 6px; /* isolate from stop/send button */
position: relative; /* important for the live circle */
@ -93,6 +93,14 @@ limitations under the License.
}
}
.mx_MessageComposer_wysiwyg .mx_VoiceMessagePrimaryContainer {
&.mx_VoiceRecordComposerTile_recording {
&::before {
top: 15px; /* vertically center (middle align with clock) */
}
}
}
/* The keyframes are slightly weird here to help make a ramping/punch effect */
/* for the recording dot. We start and end at 100% opacity to help make the */
/* dot feel a bit like a real lamp that is blinking: the animation ends up */

View file

@ -24,7 +24,7 @@ limitations under the License.
gap: 8px;
padding: 8px var(--EditWysiwygComposer-padding-inline);
.mx_WysiwygComposer_content {
.mx_WysiwygComposer_Editor_content {
border-radius: 4px;
border: solid 1px $primary-hairline-color;
background-color: $background;

View file

@ -22,32 +22,65 @@ limitations under the License.
/* fixed line height to prevent emoji from being taller than text */
line-height: $font-18px;
justify-content: center;
margin-right: 6px;
/* don't grow wider than available space */
min-width: 0;
margin-right: 13px;
gap: 8px;
.mx_WysiwygComposer_container {
flex: 1;
.mx_FormattingButtons {
margin-left: 12px;
}
.mx_WysiwygComposer_Editor {
border: 1px solid;
border-color: $quinary-content;
padding: 6px 11px 6px 12px;
display: flex;
flex-direction: column;
/* min-height at this level so the mx_BasicMessageComposer_input */
/* still stays vertically centered when less than 55px. */
/* We also set this to ensure the voice message recording widget */
/* doesn't cause a jump. */
min-height: 55px;
align-items: flex-end;
gap: 10px;
.mx_WysiwygComposer_content {
border: 1px solid;
border-radius: 20px;
padding: 8px 10px;
/* this will center the contenteditable */
/* in it's parent vertically */
/* while keeping the autocomplete at the top */
/* of the composer. The parent needs to be a flex container for this to work. */
margin: auto 0;
/* max-height at this level so autocomplete doesn't get scrolled too */
max-height: 140px;
overflow-y: auto;
.mx_E2EIcon {
margin: 0 0 7px 0;
width: 12px;
height: 12px;
}
&[data-is-expanded="true"] {
border-radius: 14px;
.mx_WysiwygComposer_Editor_container {
margin-top: 3px;
margin-bottom: 3px;
}
}
&[data-is-expanded="false"] {
border-radius: 40px;
}
.mx_WysiwygComposer_Editor_container {
flex: 1;
display: flex;
flex-direction: column;
min-height: 22px;
margin-bottom: 2px;
/* don't grow wider than available space */
width: 0;
.mx_WysiwygComposer_Editor_content {
/* this will center the contenteditable */
/* in it's parent vertically */
/* while keeping the autocomplete at the top */
/* of the composer. The parent needs to be a flex container for this to work. */
margin: auto 0;
/* max-height at this level so autocomplete doesn't get scrolled too */
max-height: 140px;
overflow-y: auto;
}
}
}
}
.mx_SendWysiwygComposer-focused {
.mx_WysiwygComposer_Editor {
border-color: $quaternary-content;
}
}

View file

@ -14,15 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_WysiwygComposer_container {
position: relative;
.mx_WysiwygComposer_Editor_container {
@keyframes visualbell {
from { background-color: $visual-bell-bg-color; }
to { background-color: $background; }
}
.mx_WysiwygComposer_content {
.mx_WysiwygComposer_Editor_content {
white-space: pre-wrap;
word-wrap: break-word;
outline: none;

View file

@ -17,6 +17,7 @@ limitations under the License.
.mx_FormattingButtons {
display: flex;
justify-content: flex-start;
gap: 8px;
.mx_FormattingButtons_Button {
--size: 28px;
@ -26,18 +27,9 @@ limitations under the License.
line-height: var(--size);
width: auto;
padding-left: 22px;
margin-right: 8px;
background-color: transparent;
border: none;
&:first-child {
margin-left: 12px;
}
&:last-child {
margin-right: auto;
}
&::before {
content: '';
position: absolute;

View file

@ -1,10 +1,34 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1456_146350)">
<path d="M1 18.6667C1 19.4 1.6 20 2.33333 20H18.3333C19.0667 20 19.6667 19.4 19.6667 18.6667C19.6667 17.9333 19.0667 17.3333 18.3333 17.3333H2.33333C1.6 17.3333 1 17.9333 1 18.6667ZM7 11.7333H13.6667L14.5467 13.8667C14.7467 14.3467 15.2133 14.6667 15.7333 14.6667C16.6533 14.6667 17.2667 13.72 16.9067 12.88L11.7333 0.92C11.4933 0.36 10.9467 0 10.3333 0C9.72 0 9.17333 0.36 8.93333 0.92L3.76 12.88C3.4 13.72 4.02667 14.6667 4.94667 14.6667C5.46667 14.6667 5.93333 14.3467 6.13333 13.8667L7 11.7333ZM10.3333 2.64L12.8267 9.33333H7.84L10.3333 2.64Z" fill="#C1C6CD"/>
</g>
<defs>
<clipPath id="clip0_1456_146350">
<rect width="20" height="20" fill="white"/>
</clipPath>
</defs>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g
clip-path="url(#clip0_1456_146365)"
id="g53">
<path
d="M7.00042 13.7333H13.6671L14.5471 15.8667C14.7471 16.3467 15.2137 16.6667 15.7337 16.6667C16.6537 16.6667 17.2671 15.72 16.9071 14.88L11.7337 2.92C11.4937 2.36 10.9471 2 10.3337 2C9.72042 2 9.17375 2.36 8.93375 2.92L3.76042 14.88C3.40042 15.72 4.02708 16.6667 4.94708 16.6667C5.46708 16.6667 5.93375 16.3467 6.13375 15.8667L7.00042 13.7333ZM10.3337 4.64L12.8271 11.3333H7.84042L10.3337 4.64Z"
fill="#C1C6CD"
id="path49" />
<path
d="m 1.497495,8.96927 c 0,0.793654 0.7402877,1.441437 1.6473569,1.441437 H 17.521786 c 0.907096,0 1.647419,-0.647783 1.647419,-1.441437 0,-0.7936857 -0.740323,-1.4414375 -1.647419,-1.4414375 H 11.127487 3.1448519 c -0.4734211,0 -0.9014103,0.1764504 -1.2024293,0.4580061 C 1.7722258,8.1450309 1.6426187,8.3378225 1.568339,8.5513189 1.522281,8.6837006 1.497495,8.8240421 1.497495,8.96927 Z"
fill="#c1c6cd"
stroke="#ffffff"
id="path51"
style="stroke:none;stroke-width:0.840525;stroke-opacity:1" />
</g>
<defs
id="defs58">
<clipPath
id="clip0_1456_146365">
<rect
width="20"
height="20"
fill="white"
id="rect55" />
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 818 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

View file

@ -1,10 +1,9 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1456_146365)">
<path d="M7.00042 13.7333H13.6671L14.5471 15.8667C14.7471 16.3467 15.2137 16.6667 15.7337 16.6667C16.6537 16.6667 17.2671 15.72 16.9071 14.88L11.7337 2.92C11.4937 2.36 10.9471 2 10.3337 2C9.72042 2 9.17375 2.36 8.93375 2.92L3.76042 14.88C3.40042 15.72 4.02708 16.6667 4.94708 16.6667C5.46708 16.6667 5.93375 16.3467 6.13375 15.8667L7.00042 13.7333ZM10.3337 4.64L12.8271 11.3333H7.84042L10.3337 4.64Z" fill="#C1C6CD"/>
<path d="M0.5 9.66927C0.5 10.6787 1.32386 11.5026 2.33333 11.5026H18.3333C19.3428 11.5026 20.1667 10.6787 20.1667 9.66927C20.1667 8.6598 19.3428 7.83594 18.3333 7.83594H2.33333C1.32386 7.83594 0.5 8.6598 0.5 9.66927Z" fill="#C1C6CD" stroke="white"/>
<g clip-path="url(#clip0_1456_146350)">
<path d="M1 18.6667C1 19.4 1.6 20 2.33333 20H18.3333C19.0667 20 19.6667 19.4 19.6667 18.6667C19.6667 17.9333 19.0667 17.3333 18.3333 17.3333H2.33333C1.6 17.3333 1 17.9333 1 18.6667ZM7 11.7333H13.6667L14.5467 13.8667C14.7467 14.3467 15.2133 14.6667 15.7333 14.6667C16.6533 14.6667 17.2667 13.72 16.9067 12.88L11.7333 0.92C11.4933 0.36 10.9467 0 10.3333 0C9.72 0 9.17333 0.36 8.93333 0.92L3.76 12.88C3.4 13.72 4.02667 14.6667 4.94667 14.6667C5.46667 14.6667 5.93333 14.3467 6.13333 13.8667L7 11.7333ZM10.3333 2.64L12.8267 9.33333H7.84L10.3333 2.64Z" fill="#C1C6CD"/>
</g>
<defs>
<clipPath id="clip0_1456_146365">
<clipPath id="clip0_1456_146350">
<rect width="20" height="20" fill="white"/>
</clipPath>
</defs>

Before

Width:  |  Height:  |  Size: 921 B

After

Width:  |  Height:  |  Size: 818 B

Before After
Before After