Merge pull request #1651 from vector-im/feature/bma/uiUpdate

Preparatory work for SecureBackup: UI update
This commit is contained in:
Benoit Marty 2023-10-27 11:03:29 +02:00 committed by GitHub
commit bf905dd79b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 375 additions and 180 deletions

View file

@ -16,41 +16,27 @@
package io.element.android.features.preferences.impl.notifications
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import io.element.android.libraries.androidutils.system.startNotificationSettingsIntent
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.designsystem.atomic.molecules.DialogLikeBannerMolecule
import io.element.android.libraries.designsystem.components.ProgressDialog
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
import io.element.android.libraries.designsystem.components.preferences.PreferencePage
import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch
import io.element.android.libraries.designsystem.components.preferences.PreferenceText
import io.element.android.libraries.designsystem.components.preferences.PreferencePage
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.ButtonSize
import io.element.android.libraries.designsystem.theme.components.Surface
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.utils.CommonDrawables
import io.element.android.libraries.designsystem.utils.OnLifecycleEvent
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.ui.strings.CommonStrings
/**
@ -197,41 +183,14 @@ private fun InvalidNotificationSettingsView(
onDismissError: () -> Unit,
modifier: Modifier = Modifier
) {
Box(modifier = modifier.padding(horizontal = 16.dp, vertical = 8.dp)) {
Surface(
Modifier.fillMaxWidth(),
shape = MaterialTheme.shapes.small,
color = MaterialTheme.colorScheme.surfaceVariant
) {
Column(
Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 12.dp)
) {
Row {
Text(
stringResource(CommonStrings.screen_notification_settings_configuration_mismatch),
modifier = Modifier.weight(1f),
style = ElementTheme.typography.fontBodyLgMedium,
color = MaterialTheme.colorScheme.primary,
textAlign = TextAlign.Start,
)
}
Spacer(modifier = Modifier.height(4.dp))
Text(
stringResource(CommonStrings.screen_notification_settings_configuration_mismatch_description),
style = ElementTheme.typography.fontBodyMdRegular,
)
Spacer(modifier = Modifier.height(12.dp))
Button(
text = stringResource(CommonStrings.action_continue),
size = ButtonSize.Medium,
modifier = Modifier.fillMaxWidth(),
onClick = onContinueClicked,
)
}
}
}
DialogLikeBannerMolecule(
modifier = modifier,
title = stringResource(CommonStrings.screen_notification_settings_configuration_mismatch),
content = stringResource(CommonStrings.screen_notification_settings_configuration_mismatch_description),
onSubmitClicked = onContinueClicked,
onDismissClicked = null,
)
if (showError) {
ErrorDialog(
title = stringResource(id = CommonStrings.dialog_title_error),

View file

@ -16,31 +16,13 @@
package io.element.android.features.roomlist.impl.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import io.element.android.features.roomlist.impl.R
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.atomic.molecules.DialogLikeBannerMolecule
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.ButtonSize
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Surface
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.utils.CommonDrawables
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@Composable
internal fun RequestVerificationHeader(
@ -48,50 +30,20 @@ internal fun RequestVerificationHeader(
onDismissClicked: () -> Unit,
modifier: Modifier = Modifier,
) {
Box(modifier = modifier.padding(horizontal = 16.dp, vertical = 8.dp)) {
Surface(
Modifier.fillMaxWidth(),
shape = MaterialTheme.shapes.small,
color = MaterialTheme.colorScheme.surfaceVariant
) {
Column(
Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 12.dp)
) {
Row {
Text(
stringResource(R.string.session_verification_banner_title),
modifier = Modifier.weight(1f),
style = ElementTheme.typography.fontBodyLgMedium,
color = MaterialTheme.colorScheme.primary,
textAlign = TextAlign.Start,
)
Icon(
modifier = Modifier.clickable(onClick = onDismissClicked),
resourceId = CommonDrawables.ic_compound_close,
contentDescription = stringResource(CommonStrings.action_close)
)
}
Spacer(modifier = Modifier.height(4.dp))
Text(
stringResource(R.string.session_verification_banner_message),
style = ElementTheme.typography.fontBodyMdRegular,
)
Spacer(modifier = Modifier.height(12.dp))
Button(
text = stringResource(CommonStrings.action_continue),
size = ButtonSize.Medium,
modifier = Modifier.fillMaxWidth(),
onClick = onVerifyClicked,
)
}
}
}
DialogLikeBannerMolecule(
modifier = modifier,
title = stringResource(R.string.session_verification_banner_title),
content = stringResource(R.string.session_verification_banner_message),
onSubmitClicked = onVerifyClicked,
onDismissClicked = onDismissClicked,
)
}
@PreviewsDayNight
@Composable
internal fun RequestVerificationHeaderPreview() = ElementPreview {
RequestVerificationHeader(onVerifyClicked = {}, onDismissClicked = {})
RequestVerificationHeader(
onVerifyClicked = {},
onDismissClicked = {},
)
}

View file

@ -0,0 +1,56 @@
/*
* 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.
*/
package io.element.android.libraries.designsystem.atomic.atoms
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.theme.ElementTheme
@Composable
fun RedIndicatorAtom(
modifier: Modifier = Modifier,
size: Dp = 10.dp,
borderSize: Dp = 1.dp,
color: Color = ElementTheme.colors.bgCriticalPrimary,
) {
Box(
modifier = modifier
.size(size)
.border(borderSize, ElementTheme.materialColors.background, CircleShape)
.padding(borderSize / 2)
.clip(CircleShape)
.background(color)
)
}
@PreviewsDayNight
@Composable
internal fun RedIndicatorAtomPreview() = ElementPreview {
RedIndicatorAtom()
}

View file

@ -0,0 +1,105 @@
/*
* 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.
*/
package io.element.android.libraries.designsystem.atomic.molecules
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.ButtonSize
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Surface
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.utils.CommonDrawables
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.ui.strings.CommonStrings
@Composable
fun DialogLikeBannerMolecule(
title: String,
content: String,
onSubmitClicked: () -> Unit,
onDismissClicked: (() -> Unit)?,
modifier: Modifier = Modifier,
) {
Box(modifier = modifier.padding(horizontal = 16.dp, vertical = 8.dp)) {
Surface(
Modifier.fillMaxWidth(),
shape = MaterialTheme.shapes.small,
color = MaterialTheme.colorScheme.surfaceVariant
) {
Column(
Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 12.dp)
) {
Row {
Text(
text = title,
modifier = Modifier.weight(1f),
style = ElementTheme.typography.fontBodyLgMedium,
color = MaterialTheme.colorScheme.primary,
textAlign = TextAlign.Start,
)
if (onDismissClicked != null) {
Icon(
modifier = Modifier.clickable(onClick = onDismissClicked),
resourceId = CommonDrawables.ic_compound_close,
contentDescription = stringResource(CommonStrings.action_close)
)
}
}
Spacer(modifier = Modifier.height(4.dp))
Text(
text = content,
style = ElementTheme.typography.fontBodyMdRegular,
)
Spacer(modifier = Modifier.height(12.dp))
Button(
text = stringResource(CommonStrings.action_continue),
size = ButtonSize.Medium,
modifier = Modifier.fillMaxWidth(),
onClick = onSubmitClicked,
)
}
}
}
}
@PreviewsDayNight
@Composable
internal fun DialogLikeBannerMoleculePreview() = ElementPreview {
DialogLikeBannerMolecule(
title = "Title",
content = "Content",
onSubmitClicked = {},
onDismissClicked = {}
)
}

View file

@ -38,6 +38,7 @@ fun ConfirmationDialog(
title: String? = null,
submitText: String = stringResource(id = CommonStrings.action_ok),
cancelText: String = stringResource(id = CommonStrings.action_cancel),
destructiveSubmit: Boolean = false,
thirdButtonText: String? = null,
onCancelClicked: () -> Unit = onDismiss,
onThirdButtonClicked: () -> Unit = {},
@ -49,6 +50,7 @@ fun ConfirmationDialog(
submitText = submitText,
cancelText = cancelText,
thirdButtonText = thirdButtonText,
destructiveSubmit = destructiveSubmit,
onSubmitClicked = onSubmitClicked,
onCancelClicked = onCancelClicked,
onThirdButtonClicked = onThirdButtonClicked,
@ -67,6 +69,7 @@ private fun ConfirmationDialogContent(
title: String? = null,
thirdButtonText: String? = null,
onThirdButtonClicked: () -> Unit = {},
destructiveSubmit: Boolean = false,
icon: @Composable (() -> Unit)? = null,
) {
SimpleAlertDialogContent(
@ -79,6 +82,7 @@ private fun ConfirmationDialogContent(
onCancelClicked = onCancelClicked,
thirdButtonText = thirdButtonText,
onThirdButtonClicked = onThirdButtonClicked,
destructiveSubmit = destructiveSubmit,
icon = icon,
)
}

View file

@ -57,6 +57,7 @@ fun PreferenceText(
icon: ImageVector? = null,
@DrawableRes iconResourceId: Int? = null,
showIconAreaIfNoIcon: Boolean = false,
showIconBadge: Boolean = false,
tintColor: Color? = null,
onClick: () -> Unit = {},
) {
@ -73,6 +74,7 @@ fun PreferenceText(
PreferenceIcon(
icon = icon,
iconResourceId = iconResourceId,
showIconBadge = showIconBadge,
enabled = enabled,
isVisible = showIconAreaIfNoIcon,
tintColor = tintColor ?: enabled.toSecondaryEnabledColor(),

View file

@ -17,17 +17,20 @@
package io.element.android.libraries.designsystem.components.preferences.components
import androidx.annotation.DrawableRes
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
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.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.atomic.atoms.RedIndicatorAtom
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Icon
@ -38,20 +41,30 @@ fun PreferenceIcon(
modifier: Modifier = Modifier,
icon: ImageVector? = null,
@DrawableRes iconResourceId: Int? = null,
showIconBadge: Boolean = false,
tintColor: Color? = null,
enabled: Boolean = true,
isVisible: Boolean = true,
) {
if (icon != null || iconResourceId != null) {
Icon(
imageVector = icon,
resourceId = iconResourceId,
contentDescription = "",
tint = tintColor ?: enabled.toSecondaryEnabledColor(),
modifier = modifier
.padding(end = 16.dp)
.size(24.dp),
)
Box(modifier = modifier) {
Icon(
imageVector = icon,
resourceId = iconResourceId,
contentDescription = "",
tint = tintColor ?: enabled.toSecondaryEnabledColor(),
modifier = Modifier
.padding(end = 16.dp)
.size(24.dp),
)
if (showIconBadge) {
RedIndicatorAtom(
modifier = Modifier
.align(Alignment.TopEnd)
.padding(end = 16.dp)
)
}
}
} else if (isVisible) {
Spacer(modifier = modifier.width(40.dp))
}
@ -60,9 +73,19 @@ fun PreferenceIcon(
@Preview(group = PreviewGroup.Preferences)
@Composable
internal fun PreferenceIconPreview(@PreviewParameter(ImageVectorProvider::class) content: ImageVector?) =
ElementThemedPreview { ContentToPreview(content) }
ElementThemedPreview {
PreferenceIcon(
icon = content,
showIconBadge = false,
)
}
@Preview(group = PreviewGroup.Preferences)
@Composable
private fun ContentToPreview(content: ImageVector?) {
PreferenceIcon(icon = content)
}
internal fun PreferenceIconWithBadgePreview(@PreviewParameter(ImageVectorProvider::class) content: ImageVector?) =
ElementThemedPreview {
PreferenceIcon(
icon = content,
showIconBadge = true,
)
}

View file

@ -57,6 +57,7 @@ internal fun SimpleAlertDialogContent(
title: String? = null,
subtitle: @Composable (() -> Unit)? = null,
submitText: String? = null,
destructiveSubmit: Boolean = false,
onSubmitClicked: () -> Unit = {},
thirdButtonText: String? = null,
onThirdButtonClicked: () -> Unit = {},
@ -76,6 +77,7 @@ internal fun SimpleAlertDialogContent(
title = title,
subtitle = subtitle,
submitText = submitText,
destructiveSubmit = destructiveSubmit,
onSubmitClicked = onSubmitClicked,
thirdButtonText = thirdButtonText,
onThirdButtonClicked = onThirdButtonClicked,
@ -92,6 +94,7 @@ internal fun SimpleAlertDialogContent(
title: String? = null,
subtitle: @Composable (() -> Unit)? = null,
submitText: String? = null,
destructiveSubmit: Boolean = false,
onSubmitClicked: () -> Unit = {},
thirdButtonText: String? = null,
onThirdButtonClicked: () -> Unit = {},
@ -126,6 +129,7 @@ internal fun SimpleAlertDialogContent(
enabled = enabled,
size = ButtonSize.Medium,
onClick = onSubmitClicked,
destructive = destructiveSubmit,
)
}
}
@ -345,8 +349,10 @@ private fun AlertDialogFlowRow(
val arrangement = Arrangement.End
val mainAxisPositions = IntArray(childrenMainAxisSizes.size) { 0 }
with(arrangement) {
arrange(mainAxisLayoutSize, childrenMainAxisSizes,
layoutDirection, mainAxisPositions)
arrange(
mainAxisLayoutSize, childrenMainAxisSizes,
layoutDirection, mainAxisPositions
)
}
placeables.forEachIndexed { j, placeable ->
placeable.place(
@ -385,22 +391,22 @@ internal object DialogContentDefaults {
val containerColor: Color
@Composable
@ReadOnlyComposable
get()= ElementTheme.colors.bgCanvasDefault
get() = ElementTheme.colors.bgCanvasDefault
val textContentColor: Color
@Composable
@ReadOnlyComposable
get()= ElementTheme.materialColors.onSurfaceVariant
get() = ElementTheme.materialColors.onSurfaceVariant
val titleContentColor: Color
@Composable
@ReadOnlyComposable
get()= ElementTheme.materialColors.onSurface
get() = ElementTheme.materialColors.onSurface
val iconContentColor: Color
@Composable
@ReadOnlyComposable
get()= ElementTheme.materialColors.primary
get() = ElementTheme.materialColors.primary
}
// Paddings for each of the dialog's parts. Taken from M3 source code.
@ -462,3 +468,21 @@ internal fun DialogWithOnlyMessageAndOkButtonPreview() {
}
}
}
@Preview(group = PreviewGroup.Dialogs, name = "Dialog with destructive button")
@Composable
@Suppress("MaxLineLength")
internal fun DialogWithDestructiveButtonPreview() {
ElementThemedPreview(showBackground = false) {
DialogPreview {
SimpleAlertDialogContent(
title = "Dialog Title",
content = "A dialog with a destructive action",
cancelText = "Cancel",
submitText = "Delete",
destructiveSubmit = true,
onCancelClicked = {},
)
}
}
}

View file

@ -20,6 +20,7 @@ import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
@ -64,6 +65,7 @@ fun Button(
enabled: Boolean = true,
size: ButtonSize = ButtonSize.Large,
showProgress: Boolean = false,
destructive: Boolean = false,
leadingIcon: IconSource? = null,
) = ButtonInternal(
text = text,
@ -73,6 +75,7 @@ fun Button(
enabled = enabled,
size = size,
showProgress = showProgress,
destructive = destructive,
leadingIcon = leadingIcon
)
@ -84,6 +87,7 @@ fun OutlinedButton(
enabled: Boolean = true,
size: ButtonSize = ButtonSize.Large,
showProgress: Boolean = false,
destructive: Boolean = false,
leadingIcon: IconSource? = null,
) = ButtonInternal(
text = text,
@ -93,6 +97,7 @@ fun OutlinedButton(
enabled = enabled,
size = size,
showProgress = showProgress,
destructive = destructive,
leadingIcon = leadingIcon
)
@ -104,6 +109,7 @@ fun TextButton(
enabled: Boolean = true,
size: ButtonSize = ButtonSize.Large,
showProgress: Boolean = false,
destructive: Boolean = false,
leadingIcon: IconSource? = null,
) = ButtonInternal(
text = text,
@ -113,6 +119,7 @@ fun TextButton(
enabled = enabled,
size = size,
showProgress = showProgress,
destructive = destructive,
leadingIcon = leadingIcon
)
@ -122,7 +129,8 @@ private fun ButtonInternal(
onClick: () -> Unit,
style: ButtonStyle,
modifier: Modifier = Modifier,
colors: ButtonColors = style.getColors(),
destructive: Boolean = false,
colors: ButtonColors = style.getColors(destructive),
enabled: Boolean = true,
size: ButtonSize = ButtonSize.Large,
showProgress: Boolean = false,
@ -170,7 +178,12 @@ private fun ButtonInternal(
ButtonStyle.Filled -> null
ButtonStyle.Outlined -> BorderStroke(
width = 1.dp,
color = ElementTheme.colors.borderInteractiveSecondary
color = if (destructive)
ElementTheme.colors.borderCriticalPrimary.copy(
alpha = if (enabled) 1f else 0.5f
)
else
ElementTheme.colors.borderInteractiveSecondary
)
ButtonStyle.Text -> null
}
@ -246,26 +259,52 @@ internal enum class ButtonStyle {
Filled, Outlined, Text;
@Composable
fun getColors(): ButtonColors = when (this) {
fun getColors(destructive: Boolean): ButtonColors = when (this) {
Filled -> ButtonDefaults.buttonColors(
containerColor = ElementTheme.materialColors.primary,
containerColor = getPrimaryColor(destructive),
contentColor = ElementTheme.materialColors.onPrimary,
disabledContainerColor = ElementTheme.colors.bgActionPrimaryDisabled,
disabledContainerColor = if (destructive) {
ElementTheme.colors.bgCriticalPrimary.copy(alpha = 0.5f)
} else {
ElementTheme.colors.bgActionPrimaryDisabled
},
disabledContentColor = ElementTheme.colors.textOnSolidPrimary
)
Outlined -> ButtonDefaults.buttonColors(
containerColor = Color.Transparent,
contentColor = ElementTheme.materialColors.primary,
contentColor = getPrimaryColor(destructive),
disabledContainerColor = Color.Transparent,
disabledContentColor = ElementTheme.colors.textDisabled,
disabledContentColor = getDisabledContentColor(destructive),
)
Text -> ButtonDefaults.buttonColors(
containerColor = Color.Transparent,
contentColor = if (LocalContentColor.current.isSpecified) LocalContentColor.current else ElementTheme.materialColors.primary,
contentColor = if (destructive) {
ElementTheme.colors.textCriticalPrimary
} else {
if (LocalContentColor.current.isSpecified) LocalContentColor.current else ElementTheme.materialColors.primary
},
disabledContainerColor = Color.Transparent,
disabledContentColor = ElementTheme.colors.textDisabled,
disabledContentColor = getDisabledContentColor(destructive),
)
}
@Composable
private fun getPrimaryColor(destructive: Boolean): Color {
return if (destructive) {
ElementTheme.colors.bgCriticalPrimary
} else {
ElementTheme.materialColors.primary
}
}
@Composable
private fun getDisabledContentColor(destructive: Boolean): Color {
return if (destructive) {
ElementTheme.colors.textCriticalPrimary.copy(alpha = 0.5f)
} else {
ElementTheme.colors.textDisabled
}
}
}
@Preview(group = PreviewGroup.Buttons)
@ -326,7 +365,6 @@ internal fun TextButtonLargePreview() {
private fun ButtonCombinationPreview(
style: ButtonStyle,
size: ButtonSize,
modifier: Modifier = Modifier,
) {
ElementThemedPreview {
Column(
@ -335,59 +373,70 @@ private fun ButtonCombinationPreview(
.padding(16.dp)
.width(IntrinsicSize.Max),
) {
// Normal
ButtonRowPreview(
modifier = Modifier.then(modifier),
style = style,
size = size,
)
// With icon
ButtonRowPreview(
modifier = Modifier.then(modifier),
leadingIcon = IconSource.Resource(CommonDrawables.ic_compound_share_android),
style = style,
size = size,
)
// With progress
ButtonRowPreview(
modifier = Modifier.then(modifier),
showProgress = true,
style = style,
size = size,
)
ButtonMatrixPreview(style = style, size = size, destructive = false)
ButtonMatrixPreview(style = style, size = size, destructive = true)
}
}
}
@Composable
private fun ColumnScope.ButtonMatrixPreview(
style: ButtonStyle,
size: ButtonSize,
destructive: Boolean,
) {
// Normal
ButtonRowPreview(
style = style,
size = size,
destructive = destructive,
)
// With icon
ButtonRowPreview(
leadingIcon = IconSource.Resource(CommonDrawables.ic_compound_share_android),
style = style,
size = size,
destructive = destructive,
)
// With progress
ButtonRowPreview(
showProgress = true,
style = style,
size = size,
destructive = destructive,
)
}
@Composable
private fun ButtonRowPreview(
style: ButtonStyle,
size: ButtonSize,
modifier: Modifier = Modifier,
leadingIcon: IconSource? = null,
showProgress: Boolean = false,
destructive: Boolean = false,
) {
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally)) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally),
) {
ButtonInternal(
text = "A button",
showProgress = showProgress,
destructive = destructive,
onClick = {},
style = style,
size = size,
leadingIcon = leadingIcon,
modifier = Modifier.then(modifier),
)
ButtonInternal(
text = "A button",
showProgress = showProgress,
destructive = destructive,
enabled = false,
onClick = {},
style = style,
size = size,
leadingIcon = leadingIcon,
modifier = Modifier.then(modifier),
)
}
}

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f54912dfb9235aa915025d496f280de362286997f746481da41deb02a1ec67e3
size 4768

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ae078e1bb55967e9e583a588b4fb410eb0417d944b20911158b24f3824ee6dca
size 4752

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:45736b242f9bf1a50fb14af9b340633f0fdc348ed7a846c4c57c3a56a4b2a48c
size 11429

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1f9989dadb7c68cf705683997689f48595be9283eb939d934819399ec3c6805f
size 11209

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a6d2243cb6bedd4b7a2f1c8c9b5aeac8356642271061c1439e591ce07c55c822
size 6390

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a2d302d58c1faec3c3f0aa3286977b2698cd642c1e6dbcb9632510c6a4a922eb
size 4501

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d0f2dc7bfcf59bf26362775625ddc9dedf53f400057997560628614136e2880b
size 44144
oid sha256:222795141c044e5bd7929cb9b894535124a176fd88347eea83037116f4ba6e8b
size 68192

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1e240c572aab6db77995c93787a7b0aaba76060861c45934eb87d4ba48c5675c
size 42789
oid sha256:b2d816dac6d468ede766719ec854cd575c89f454346ddd6ef8048c836bd04c14
size 66223

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:54497bfab92c6ed850f753df61a31366ca68d41c7d90e322e7cc7eceb6dd4277
size 48139
oid sha256:a8d423b71168b3bd5dab8da01376fa3f114865aa0d4eb48d41fccfb4640367e3
size 77867

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e7d3f2e50b395f86ed7c78146d5a428b099c672d763c278c1b2899d915abf717
size 47615
oid sha256:5381c6f070f2c81019ce39af5902f6f2c683c7ce4db4636b3b3259fdca270cdf
size 75884

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:876eba4a9f8214aa2d33dad84ccbbb95994c615f25f158cb6596fd4512241bd9
size 31582
oid sha256:093a5bd68ebca0a9eaf8cac3cf748514cc0f3165c1079016d54d40762c7c0287
size 46434

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3dd7259e0b14b9ad5e9a6aed46383f91822ee11f1e77b0f2cdc5d2e0b38f7abd
size 29702
oid sha256:dfa423f2008049e54046449c19615eb66f28e7e66645eff76e80e33062b5c59a
size 43655

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a3079a82a70fc20feac8c694a8571eac5dac9e2dea800bd7ca01628fe7c90d29
size 33019