Updated on 2026-08-14
This commit is contained in:
parent
76f955568e
commit
fc8fcfce19
17 changed files with 395 additions and 133 deletions
143
core/ui/src/main/java/com/tangem/core/ui/components/Dialogs.kt
Normal file
143
core/ui/src/main/java/com/tangem/core/ui/components/Dialogs.kt
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
package com.tangem.core.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.AlertDialog
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
/**
|
||||
* Simple alert dialog with a message and 'OK' button
|
||||
*
|
||||
* @param message message to show
|
||||
* @param title title to show (no title if null)
|
||||
* @param confirmButton title and action for confirm button
|
||||
* @param dismissButton title and action for dismiss button (no dismiss button if null)
|
||||
* @param onDismissDialog action to perform when dialog is closed
|
||||
*
|
||||
* @see <a href = "https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?node-id=48%3A30&t=izDPAJnDbJTTC0Fp-1"
|
||||
* >Figma component</a>
|
||||
*/
|
||||
@Composable
|
||||
fun BasicDialog(
|
||||
modifier: Modifier = Modifier,
|
||||
message: String,
|
||||
title: String? = null,
|
||||
confirmButton: DialogButton,
|
||||
dismissButton: DialogButton? = null,
|
||||
onDismissDialog: () -> Unit,
|
||||
) {
|
||||
AlertDialog(
|
||||
text = {
|
||||
Text(
|
||||
text = message,
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
)
|
||||
},
|
||||
title = if (title != null) {
|
||||
{
|
||||
Text(
|
||||
text = title,
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
},
|
||||
onDismissRequest = onDismissDialog,
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
|
||||
text = confirmButton.title ?: stringResource(id = R.string.common_ok),
|
||||
onClick = confirmButton.onClick,
|
||||
)
|
||||
},
|
||||
dismissButton = {
|
||||
if (dismissButton != null) {
|
||||
TextButton(
|
||||
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
|
||||
text = dismissButton.title ?: stringResource(id = R.string.common_cancel),
|
||||
onClick = dismissButton.onClick,
|
||||
)
|
||||
}
|
||||
},
|
||||
shape = TangemTheme.shapes.roundedCornersLarge,
|
||||
modifier = modifier
|
||||
.padding(TangemTheme.dimens.spacing24),
|
||||
)
|
||||
}
|
||||
|
||||
data class DialogButton(
|
||||
val title: String? = null,
|
||||
val onClick: () -> Unit,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun SimpleOkDialog(
|
||||
modifier: Modifier = Modifier,
|
||||
message: String,
|
||||
onDismissDialog: () -> Unit,
|
||||
) {
|
||||
BasicDialog(
|
||||
modifier = modifier,
|
||||
message = message,
|
||||
confirmButton = DialogButton(onClick = onDismissDialog),
|
||||
onDismissDialog = onDismissDialog,
|
||||
)
|
||||
}
|
||||
|
||||
// region Preview
|
||||
|
||||
@Composable
|
||||
private fun SimpleOkDialogPreview() = SimpleOkDialog(
|
||||
message = "All protected passwords will be deleted from the " +
|
||||
"secure storage, you must enter the wallet password to work with the app.",
|
||||
) {}
|
||||
|
||||
@Composable
|
||||
private fun BasicDialogPreview() = BasicDialog(
|
||||
message = "All protected passwords will be deleted from the secure storage, you must enter the wallet password to work with the app",
|
||||
title = "Attention",
|
||||
confirmButton = DialogButton {},
|
||||
dismissButton = DialogButton {},
|
||||
) {}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun Preview_SimpleOkDialog_InLightTheme() {
|
||||
TangemTheme(isDark = false) {
|
||||
SimpleOkDialogPreview()
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun Preview_BasicDialog_InLightTheme() {
|
||||
TangemTheme(isDark = false) {
|
||||
BasicDialogPreview()
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun Preview_SimpleOkDialog_InDarkTheme() {
|
||||
TangemTheme(isDark = true) {
|
||||
SimpleOkDialogPreview()
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun Preview_BasicDialog_InDarkTheme() {
|
||||
TangemTheme(isDark = true) {
|
||||
BasicDialogPreview()
|
||||
}
|
||||
}
|
||||
|
||||
// endregion Preview
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package com.tangem.core.ui.components
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
|
|
@ -18,6 +20,7 @@ import androidx.compose.material.Text
|
|||
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.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
|
|
@ -26,25 +29,37 @@ import com.tangem.core.ui.R
|
|||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
/**
|
||||
* Screen for showing success
|
||||
* Screen for showing result
|
||||
*
|
||||
* @param successMessage
|
||||
* @param resultMessage message to show
|
||||
* @param title title to show
|
||||
* @param resultColor color which will tint the round icon of the result
|
||||
* @param icon icon to show in the middle of the round icon
|
||||
* @param secondaryButtonIcon icon to show in the secondary button
|
||||
* @param secondaryButtonText label of the secondary button
|
||||
* @param onSecondaryButtonClick action on clicking secondary button
|
||||
* @param onButtonClick action on clicking "Done" button
|
||||
*
|
||||
* @see <a href = "https://www.figma.com/file/Vs6SkVsFnUPsSCNwlnVf5U/Android-%E2%80%93-UI?node-id=1123%3A3863&t=wwR84h5IsMaMsDhq-1"
|
||||
* >Figma component</a>
|
||||
*/
|
||||
@Composable
|
||||
fun SuccessScreenContent(
|
||||
fun ResultScreenContent(
|
||||
modifier: Modifier = Modifier,
|
||||
successMessage: String,
|
||||
resultMessage: String,
|
||||
@StringRes title: Int = R.string.common_success,
|
||||
resultColor: Color = TangemTheme.colors.icon.accent,
|
||||
@DrawableRes icon: Int = R.drawable.ic_check_24,
|
||||
@DrawableRes secondaryButtonIcon: Int? = null,
|
||||
@StringRes secondaryButtonText: Int? = null,
|
||||
onSecondaryButtonClick: (() -> Unit)? = null,
|
||||
onButtonClick: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.background(TangemTheme.colors.background.primary)
|
||||
.background(TangemTheme.colors.background.secondary)
|
||||
.padding(
|
||||
horizontal = TangemTheme.dimens.spacing16,
|
||||
vertical = TangemTheme.dimens.spacing32,
|
||||
|
|
@ -53,10 +68,10 @@ fun SuccessScreenContent(
|
|||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
SpacerHHalf()
|
||||
SuccessImage()
|
||||
SuccessImage(resultColor = resultColor, icon = icon)
|
||||
SpacerH50()
|
||||
Text(
|
||||
text = stringResource(id = R.string.common_success),
|
||||
text = stringResource(id = title),
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
|
|
@ -64,15 +79,25 @@ fun SuccessScreenContent(
|
|||
)
|
||||
SpacerH12()
|
||||
Text(
|
||||
text = successMessage,
|
||||
text = resultMessage,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
SpacerHHalf()
|
||||
if (onSecondaryButtonClick != null && secondaryButtonText != null) {
|
||||
SecondaryButtonForResultScreen(
|
||||
secondaryButtonText = secondaryButtonText,
|
||||
secondaryButtonIcon = secondaryButtonIcon,
|
||||
onSecondaryButtonClick = onSecondaryButtonClick,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
SpacerH12()
|
||||
}
|
||||
PrimaryButton(
|
||||
text = stringResource(id = R.string.common_done),
|
||||
text = stringResource(id = R.string.common_close),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
onClick = { onButtonClick() },
|
||||
|
|
@ -81,11 +106,15 @@ fun SuccessScreenContent(
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun SuccessImage() {
|
||||
fun SuccessImage(
|
||||
resultColor: Color,
|
||||
@DrawableRes icon: Int,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.background(
|
||||
color = TangemTheme.colors.icon.accent.copy(alpha = 0.2f),
|
||||
color = (resultColor)
|
||||
.copy(alpha = 0.2f),
|
||||
shape = CircleShape,
|
||||
),
|
||||
contentAlignment = Alignment.Center,
|
||||
|
|
@ -94,7 +123,7 @@ fun SuccessImage() {
|
|||
modifier = Modifier
|
||||
.padding(TangemTheme.dimens.spacing24)
|
||||
.background(
|
||||
color = TangemTheme.colors.icon.accent,
|
||||
color = resultColor,
|
||||
shape = CircleShape,
|
||||
)
|
||||
.height(TangemTheme.dimens.size93)
|
||||
|
|
@ -102,7 +131,7 @@ fun SuccessImage() {
|
|||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_check_24),
|
||||
painter = painterResource(id = icon),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.primary2,
|
||||
modifier = Modifier.size(TangemTheme.dimens.size40),
|
||||
|
|
@ -111,12 +140,37 @@ fun SuccessImage() {
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SecondaryButtonForResultScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
@StringRes secondaryButtonText: Int,
|
||||
@DrawableRes secondaryButtonIcon: Int? = null,
|
||||
onSecondaryButtonClick: (() -> Unit),
|
||||
) {
|
||||
if (secondaryButtonIcon != null) {
|
||||
SecondaryButtonIconLeft(
|
||||
text = stringResource(id = secondaryButtonText),
|
||||
icon = painterResource(id = secondaryButtonIcon),
|
||||
onClick = onSecondaryButtonClick,
|
||||
modifier = modifier,
|
||||
)
|
||||
} else {
|
||||
SecondaryButton(
|
||||
text = stringResource(id = secondaryButtonText),
|
||||
onClick = onSecondaryButtonClick,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// region preview
|
||||
|
||||
@Composable
|
||||
private fun SuccessScreenPreview() {
|
||||
SuccessScreenContent(
|
||||
successMessage = "Swap of 1 000 DAI to 1 131,46 MATIC",
|
||||
ResultScreenContent(
|
||||
resultMessage = "Swap of 1 000 DAI to 1 131,46 MATIC",
|
||||
secondaryButtonText = R.string.swapping_success_view_explorer_button_title,
|
||||
onSecondaryButtonClick = {},
|
||||
onButtonClick = {},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ fun WarningCard(
|
|||
modifier: Modifier = Modifier,
|
||||
title: String,
|
||||
description: String,
|
||||
icon: @Composable (() -> Unit)? = null,
|
||||
) {
|
||||
WarningCardSurface(
|
||||
modifier = modifier,
|
||||
|
|
@ -35,6 +36,7 @@ fun WarningCard(
|
|||
WarningBody(
|
||||
title = title,
|
||||
description = description,
|
||||
icon = icon,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -55,12 +57,13 @@ fun ClickableWarningCard(
|
|||
modifier: Modifier = Modifier,
|
||||
title: String,
|
||||
description: String,
|
||||
icon: @Composable (() -> Unit)? = null,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
WarningCardSurface(
|
||||
modifier = modifier,
|
||||
content = {
|
||||
WarningBody(title = title, description = description) {
|
||||
WarningBody(title = title, description = description, icon = icon) {
|
||||
SpacerW12()
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_chevron_right_24),
|
||||
|
|
@ -88,12 +91,13 @@ fun RefreshableWaringCard(
|
|||
modifier: Modifier = Modifier,
|
||||
title: String,
|
||||
description: String,
|
||||
icon: @Composable (() -> Unit)? = null,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
WarningCardSurface(
|
||||
modifier = modifier,
|
||||
content = {
|
||||
WarningBody(title = title, description = description) {
|
||||
WarningBody(title = title, description = description, icon = icon) {
|
||||
SpacerW12()
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_refresh_24),
|
||||
|
|
@ -113,6 +117,7 @@ private fun WarningBody(
|
|||
modifier: Modifier = Modifier,
|
||||
title: String,
|
||||
description: String,
|
||||
icon: @Composable (() -> Unit)? = null,
|
||||
additionalContent: @Composable () -> Unit = {},
|
||||
) {
|
||||
IconWithTitleAndDescription(
|
||||
|
|
@ -120,7 +125,7 @@ private fun WarningBody(
|
|||
title = title,
|
||||
description = description,
|
||||
additionalContent = additionalContent,
|
||||
icon = {
|
||||
icon = icon ?: {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.img_attention_20),
|
||||
contentDescription = null,
|
||||
|
|
|
|||
10
core/ui/src/main/res/drawable/ic_arrow_top_right_24.xml
Normal file
10
core/ui/src/main/res/drawable/ic_arrow_top_right_24.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:autoMirrored="true"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M5,17.59L15.59,7H9V5H19V15H17V8.41L6.41,19L5,17.59Z" />
|
||||
</vector>
|
||||
Loading…
Add table
Add a link
Reference in a new issue