[Rich text editor] Update design (#1332)
* Fix composer height and padding * Update plus and cancel icons with design system icons * Update border so that it is always visible * Update placeholder color * Update send and tick icons * Update design of formatting buttons * Update RTE icons * Reduce bottom padding --------- Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
parent
2d98b397c6
commit
6563dca4f2
47 changed files with 282 additions and 165 deletions
|
|
@ -114,7 +114,7 @@ fun TextComposer(
|
|||
start = 3.dp,
|
||||
end = 6.dp,
|
||||
top = 8.dp,
|
||||
bottom = 5.dp,
|
||||
bottom = 4.dp,
|
||||
)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
|
|
@ -137,7 +137,7 @@ fun TextComposer(
|
|||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(30.dp.applyScaleUp()),
|
||||
resourceId = R.drawable.ic_plus, // TODO Replace with design system icon when available
|
||||
resourceId = VectorIcons.Plus,
|
||||
contentDescription = stringResource(R.string.rich_text_editor_a11y_add_attachment),
|
||||
tint = ElementTheme.colors.iconPrimary,
|
||||
)
|
||||
|
|
@ -146,7 +146,7 @@ fun TextComposer(
|
|||
val roundCornerLarge = 28.dp.applyScaleUp()
|
||||
|
||||
val roundedCornerSize = remember(state.lineCount, composerMode) {
|
||||
if (state.lineCount > 1 || composerMode is MessageComposerMode.Special) {
|
||||
if (composerMode is MessageComposerMode.Special) {
|
||||
roundCornerSmall
|
||||
} else {
|
||||
roundCornerLarge
|
||||
|
|
@ -156,17 +156,13 @@ fun TextComposer(
|
|||
targetValue = roundedCornerSize,
|
||||
animationSpec = tween(
|
||||
durationMillis = 100,
|
||||
)
|
||||
),
|
||||
label = "roundedCornerSizeAnimation"
|
||||
)
|
||||
val roundedCorners = RoundedCornerShape(roundedCornerSizeState.value)
|
||||
val colors = ElementTheme.colors
|
||||
val bgColor = colors.bgSubtleSecondary
|
||||
|
||||
val borderColor by remember(state.hasFocus, colors) {
|
||||
derivedStateOf {
|
||||
if (state.hasFocus) colors.borderDisabled else bgColor
|
||||
}
|
||||
}
|
||||
val borderColor = colors.borderDisabled
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
|
@ -180,7 +176,7 @@ fun TextComposer(
|
|||
.fillMaxWidth()
|
||||
.clip(roundedCorners)
|
||||
.background(color = bgColor)
|
||||
.border(1.dp, borderColor, roundedCorners)
|
||||
.border(0.5.dp, borderColor, roundedCorners)
|
||||
) {
|
||||
if (composerMode is MessageComposerMode.Special) {
|
||||
ComposerModeView(composerMode = composerMode, onResetComposerMode = onResetComposerMode)
|
||||
|
|
@ -272,7 +268,7 @@ private fun TextInput(
|
|||
Text(
|
||||
placeholder,
|
||||
style = defaultTypography.copy(
|
||||
color = ElementTheme.colors.textDisabled,
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -280,6 +276,7 @@ private fun TextInput(
|
|||
RichTextEditor(
|
||||
state = state,
|
||||
modifier = Modifier
|
||||
.padding(top = 6.dp, bottom = 6.dp)
|
||||
.fillMaxWidth(),
|
||||
style = RichTextEditorDefaults.style(
|
||||
text = RichTextEditorDefaults.textStyle(
|
||||
|
|
@ -323,7 +320,7 @@ private fun TextFormatting(
|
|||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(30.dp.applyScaleUp()),
|
||||
resourceId = R.drawable.ic_cancel, // TODO Replace with design system icon when available
|
||||
resourceId = VectorIcons.Cancel,
|
||||
contentDescription = stringResource(CommonStrings.action_close),
|
||||
tint = ElementTheme.colors.iconPrimary,
|
||||
)
|
||||
|
|
@ -335,8 +332,8 @@ private fun TextFormatting(
|
|||
.constrainAs(formatting) {
|
||||
top.linkTo(parent.top)
|
||||
bottom.linkTo(parent.bottom)
|
||||
start.linkTo(close.end, margin = 3.dp)
|
||||
end.linkTo(send.start, margin = 20.dp)
|
||||
start.linkTo(close.end, margin = 1.dp)
|
||||
end.linkTo(send.start, margin = 14.dp)
|
||||
width = fillToConstraints
|
||||
}
|
||||
.horizontalScroll(scrollState),
|
||||
|
|
@ -589,7 +586,7 @@ private fun SendButton(
|
|||
) {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.height(18.dp.applyScaleUp())
|
||||
.height(24.dp.applyScaleUp())
|
||||
.align(Alignment.Center),
|
||||
resourceId = iconId,
|
||||
contentDescription = contentDescription,
|
||||
|
|
|
|||
|
|
@ -18,17 +18,26 @@ package io.element.android.libraries.textcomposer.components
|
|||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.VectorIcons
|
||||
import io.element.android.libraries.designsystem.preview.DayNightPreviews
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.text.applyScaleUp
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.iconSuccessPrimaryBackground
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
import io.element.android.libraries.theme.compound.generated.SemanticColors
|
||||
|
||||
|
|
@ -42,27 +51,65 @@ internal fun FormattingOption(
|
|||
colors: SemanticColors = ElementTheme.colors,
|
||||
) {
|
||||
val backgroundColor = when (state) {
|
||||
FormattingOptionState.Selected -> colors.bgActionPrimaryRest
|
||||
FormattingOptionState.Selected -> colors.iconSuccessPrimaryBackground
|
||||
FormattingOptionState.Default,
|
||||
FormattingOptionState.Disabled -> Color.Transparent
|
||||
}
|
||||
|
||||
val foregroundColor = when (state) {
|
||||
FormattingOptionState.Selected -> colors.iconOnSolidPrimary
|
||||
FormattingOptionState.Default -> colors.iconPrimary
|
||||
FormattingOptionState.Selected -> colors.iconSuccessPrimary
|
||||
FormattingOptionState.Default -> colors.iconSecondary
|
||||
FormattingOptionState.Disabled -> colors.iconDisabled
|
||||
}
|
||||
Box(
|
||||
modifier = modifier
|
||||
.clickable { onClick() }
|
||||
.size(44.dp.applyScaleUp())
|
||||
.background(backgroundColor, shape = RoundedCornerShape(4.dp.applyScaleUp()))
|
||||
.clickable(
|
||||
onClick = onClick,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = rememberRipple(
|
||||
bounded = false,
|
||||
radius = 20.dp,
|
||||
),
|
||||
)
|
||||
.size(48.dp.applyScaleUp())
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
imageVector = imageVector,
|
||||
contentDescription = contentDescription,
|
||||
tint = foregroundColor,
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(36.dp.applyScaleUp())
|
||||
.align(Alignment.Center)
|
||||
.background(backgroundColor, shape = RoundedCornerShape(8.dp.applyScaleUp()))
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
imageVector = imageVector,
|
||||
contentDescription = contentDescription,
|
||||
tint = foregroundColor,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DayNightPreviews
|
||||
@Composable
|
||||
internal fun FormattingButtonPreview() = ElementPreview {
|
||||
Row {
|
||||
FormattingOption(
|
||||
state = FormattingOptionState.Default,
|
||||
onClick = { },
|
||||
imageVector = ImageVector.vectorResource(VectorIcons.Bold),
|
||||
contentDescription = "",
|
||||
)
|
||||
FormattingOption(
|
||||
state = FormattingOptionState.Selected,
|
||||
onClick = { },
|
||||
imageVector = ImageVector.vectorResource(VectorIcons.Italic),
|
||||
contentDescription = "",
|
||||
)
|
||||
FormattingOption(
|
||||
state = FormattingOptionState.Disabled,
|
||||
onClick = { },
|
||||
imageVector = ImageVector.vectorResource(VectorIcons.Underline),
|
||||
contentDescription = "",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="32"
|
||||
android:viewportHeight="32">
|
||||
<path
|
||||
android:pathData="M16,18.121L19.182,21.303C19.483,21.604 19.836,21.754 20.243,21.754C20.649,21.754 21.003,21.604 21.303,21.303C21.604,21.003 21.754,20.649 21.754,20.243C21.754,19.836 21.604,19.483 21.303,19.182L18.121,16L21.303,12.818C21.604,12.517 21.754,12.164 21.754,11.757C21.754,11.351 21.604,10.997 21.303,10.697C21.003,10.396 20.649,10.246 20.243,10.246C19.836,10.246 19.483,10.396 19.182,10.697L16,13.879L12.818,10.697C12.517,10.396 12.164,10.246 11.757,10.246C11.351,10.246 10.997,10.396 10.697,10.697C10.396,10.997 10.246,11.351 10.246,11.757C10.246,12.164 10.396,12.517 10.697,12.818L13.879,16L10.697,19.182C10.396,19.483 10.246,19.836 10.246,20.243C10.246,20.649 10.396,21.003 10.697,21.303C10.997,21.604 11.351,21.754 11.757,21.754C12.164,21.754 12.517,21.604 12.818,21.303L16,18.121ZM26.607,26.607C25.139,28.074 23.482,29.174 21.635,29.908C19.787,30.642 17.909,31.008 16,31.008C14.091,31.008 12.213,30.642 10.365,29.908C8.518,29.174 6.861,28.074 5.393,26.607C3.926,25.139 2.826,23.482 2.092,21.635C1.358,19.787 0.992,17.909 0.992,16C0.992,14.091 1.358,12.213 2.092,10.365C2.826,8.518 3.926,6.861 5.393,5.393C6.861,3.926 8.518,2.826 10.365,2.092C12.213,1.358 14.091,0.992 16,0.992C17.909,0.992 19.787,1.358 21.635,2.092C23.482,2.826 25.139,3.926 26.607,5.393C28.074,6.861 29.174,8.518 29.908,10.365C30.642,12.213 31.008,14.091 31.008,16C31.008,17.909 30.642,19.787 29.908,21.635C29.174,23.482 28.074,25.139 26.607,26.607Z"
|
||||
android:fillColor="#1B1D22"/>
|
||||
</vector>
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="30"
|
||||
android:viewportHeight="30">
|
||||
<path
|
||||
android:pathData="M13.5,16.5V21C13.5,21.425 13.644,21.781 13.931,22.069C14.219,22.356 14.575,22.5 15,22.5C15.425,22.5 15.781,22.356 16.069,22.069C16.356,21.781 16.5,21.425 16.5,21V16.5H21C21.425,16.5 21.781,16.356 22.069,16.069C22.356,15.781 22.5,15.425 22.5,15C22.5,14.575 22.356,14.219 22.069,13.931C21.781,13.644 21.425,13.5 21,13.5H16.5V9C16.5,8.575 16.356,8.219 16.069,7.931C15.781,7.644 15.425,7.5 15,7.5C14.575,7.5 14.219,7.644 13.931,7.931C13.644,8.219 13.5,8.575 13.5,9V13.5H9C8.575,13.5 8.219,13.644 7.931,13.931C7.644,14.219 7.5,14.575 7.5,15C7.5,15.425 7.644,15.781 7.931,16.069C8.219,16.356 8.575,16.5 9,16.5H13.5ZM15,30C12.925,30 10.975,29.606 9.15,28.819C7.325,28.031 5.738,26.962 4.387,25.612C3.037,24.263 1.969,22.675 1.181,20.85C0.394,19.025 0,17.075 0,15C0,12.925 0.394,10.975 1.181,9.15C1.969,7.325 3.037,5.738 4.387,4.387C5.738,3.037 7.325,1.969 9.15,1.181C10.975,0.394 12.925,0 15,0C17.075,0 19.025,0.394 20.85,1.181C22.675,1.969 24.263,3.037 25.612,4.387C26.962,5.738 28.031,7.325 28.819,9.15C29.606,10.975 30,12.925 30,15C30,17.075 29.606,19.025 28.819,20.85C28.031,22.675 26.962,24.263 25.612,25.612C24.263,26.962 22.675,28.031 20.85,28.819C19.025,29.606 17.075,30 15,30Z"
|
||||
android:fillColor="#1B1D22"/>
|
||||
</vector>
|
||||
|
|
@ -1,9 +1,25 @@
|
|||
<!--
|
||||
~ Copyright (c) 2023 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.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="21dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="21"
|
||||
android:viewportHeight="18">
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M20.252,10.085 L4.681,17.867c-1.049,0.525 -2.141,-0.601 -1.628,-1.627 0,0 1.93,-3.897 2.461,-4.918 0.531,-1.021 1.138,-1.197 6.781,-1.927 0.209,-0.027 0.38,-0.185 0.38,-0.395 0,-0.21 -0.171,-0.368 -0.38,-0.395C6.652,7.876 6.045,7.699 5.514,6.678 4.983,5.658 3.053,1.76 3.053,1.76 2.54,0.734 3.632,-0.391 4.681,0.133L20.252,7.915c0.894,0.446 0.894,1.723 0,2.17z"
|
||||
android:fillColor="@android:color/white"/>
|
||||
android:pathData="M21.829,13.085 L6.259,20.867c-1.049,0.525 -2.141,-0.601 -1.628,-1.627 0,0 1.93,-3.897 2.461,-4.918 0.531,-1.021 1.138,-1.197 6.781,-1.927 0.209,-0.027 0.38,-0.185 0.38,-0.395 0,-0.21 -0.171,-0.368 -0.38,-0.395C8.23,10.876 7.622,10.699 7.091,9.678c-0.531,-1.02 -2.461,-4.918 -2.461,-4.918 -0.513,-1.026 0.579,-2.152 1.628,-1.627L21.829,10.915c0.894,0.446 0.894,1.723 0,2.17z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="16dp"
|
||||
android:height="15dp"
|
||||
android:viewportWidth="16"
|
||||
android:viewportHeight="15">
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M6.518,14.779C6.953,14.779 7.297,14.597 7.535,14.233L15.403,1.968C15.579,1.692 15.65,1.461 15.65,1.234C15.65,0.657 15.245,0.26 14.662,0.26C14.249,0.26 14.009,0.399 13.759,0.792L6.484,12.348L2.736,7.529C2.492,7.205 2.236,7.07 1.874,7.07C1.277,7.07 0.857,7.489 0.857,8.066C0.857,8.315 0.95,8.565 1.158,8.819L5.495,14.245C5.784,14.606 6.096,14.779 6.518,14.779Z"
|
||||
android:pathData="M9.55,17.575C9.417,17.575 9.292,17.555 9.175,17.513C9.058,17.471 8.95,17.4 8.85,17.3L4.55,13C4.367,12.817 4.279,12.58 4.288,12.288C4.296,11.996 4.392,11.759 4.575,11.575C4.758,11.392 4.992,11.3 5.275,11.3C5.558,11.3 5.792,11.392 5.975,11.575L9.55,15.15L18.025,6.675C18.208,6.492 18.446,6.4 18.737,6.4C19.029,6.4 19.267,6.492 19.45,6.675C19.633,6.859 19.725,7.096 19.725,7.388C19.725,7.68 19.633,7.917 19.45,8.1L10.25,17.3C10.15,17.4 10.042,17.471 9.925,17.513C9.808,17.555 9.683,17.575 9.55,17.575Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue