Updated on 2026-08-14

This commit is contained in:
Tangem 2026-02-20 12:52:01 +05:00
parent afc8971b58
commit 0f961af7ce
12 changed files with 294 additions and 200 deletions

View file

@ -72,14 +72,14 @@ fun TangemBadge(badgeUM: TangemBadgeUM, modifier: Modifier = Modifier) {
*/
@Composable
fun TangemBadge(
text: TextReference,
modifier: Modifier = Modifier,
text: TextReference? = null,
@DrawableRes iconRes: Int? = null,
size: TangemBadgeSize = X9,
shape: TangemBadgeShape = TangemBadgeShape.Default,
color: TangemBadgeColor = TangemBadgeColor.Gray,
type: TangemBadgeType = TangemBadgeType.Solid,
iconPosition: TangemBadgeIconPosition = TangemBadgeIconPosition.Start,
iconPosition: TangemBadgeIconPosition = TangemBadgeIconPosition.None,
onClick: (() -> Unit)? = null,
) {
val iconColor = getIconColor(type = type, color = color)
@ -94,7 +94,7 @@ fun TangemBadge(
.clickableSingle(enabled = onClick != null, onClick = { onClick?.invoke() }),
) {
AnimatedVisibility(
visible = iconRes != null && iconPosition == TangemBadgeIconPosition.Start,
visible = iconRes != null && iconPosition != TangemBadgeIconPosition.End,
modifier = Modifier.size(size = size.toContentSize()),
label = "Start Icon Visibility",
) {
@ -105,13 +105,18 @@ fun TangemBadge(
tint = iconColor,
)
}
Text(
text = text.resolveReference(),
style = size.toTextStyle(),
maxLines = 1,
color = getTextColor(type = type, color = color),
)
AnimatedVisibility(
visible = text != null,
label = "Text Visibility",
) {
val wrappedText = remember(this) { requireNotNull(text) }
Text(
text = wrappedText.resolveReference(),
style = size.toTextStyle(),
maxLines = 1,
color = getTextColor(type = type, color = color),
)
}
AnimatedVisibility(
visible = iconRes != null && iconPosition == TangemBadgeIconPosition.End,
modifier = Modifier.size(size = size.toContentSize()),
@ -178,14 +183,17 @@ enum class TangemBadgeSize {
X4 -> when (position) {
TangemBadgeIconPosition.Start -> PaddingValues(start = 4.dp, end = 6.dp)
TangemBadgeIconPosition.End -> PaddingValues(start = 6.dp, end = 4.dp)
TangemBadgeIconPosition.None -> PaddingValues(start = 6.dp, end = 6.dp)
}
X6 -> when (position) {
TangemBadgeIconPosition.Start -> PaddingValues(start = 8.dp, end = 12.dp)
TangemBadgeIconPosition.End -> PaddingValues(start = 12.dp, end = 8.dp)
TangemBadgeIconPosition.None -> PaddingValues(start = 12.dp, end = 12.dp)
}
X9 -> when (position) {
TangemBadgeIconPosition.Start -> PaddingValues(start = 12.dp, end = 16.dp)
TangemBadgeIconPosition.End -> PaddingValues(start = 16.dp, end = 12.dp)
TangemBadgeIconPosition.None -> PaddingValues(start = 16.dp, end = 16.dp)
}
}
@ -222,6 +230,7 @@ enum class TangemBadgeSize {
enum class TangemBadgeIconPosition {
Start,
End,
None,
}
/**
@ -240,6 +249,7 @@ enum class TangemBadgeColor {
Blue,
Red,
Gray,
Green,
}
@ReadOnlyComposable
@ -258,6 +268,12 @@ private fun getIconColor(type: TangemBadgeType, color: TangemBadgeColor) = when
-> TangemTheme.colors2.markers.iconRed
TangemBadgeType.Solid -> TangemTheme.colors2.graphic.neutral.primaryInvertedConstant
}
TangemBadgeColor.Green -> when (type) {
TangemBadgeType.Outline,
TangemBadgeType.Tinted,
-> TangemTheme.colors2.markers.iconGreen
TangemBadgeType.Solid -> TangemTheme.colors2.graphic.neutral.primaryInvertedConstant
}
}
@ReadOnlyComposable
@ -276,8 +292,15 @@ private fun getTextColor(type: TangemBadgeType, color: TangemBadgeColor) = when
-> TangemTheme.colors2.markers.textRed
TangemBadgeType.Solid -> TangemTheme.colors2.text.neutral.primaryInvertedConstant
}
TangemBadgeColor.Green -> when (type) {
TangemBadgeType.Outline,
TangemBadgeType.Tinted,
-> TangemTheme.colors2.markers.textGreen
TangemBadgeType.Solid -> TangemTheme.colors2.text.neutral.primaryInvertedConstant
}
}
@Suppress("CyclomaticComplexMethod")
@ReadOnlyComposable
@Composable
private fun Modifier.getBackgroundColor(type: TangemBadgeType, color: TangemBadgeColor, shape: Shape) = when (type) {
@ -286,6 +309,7 @@ private fun Modifier.getBackgroundColor(type: TangemBadgeType, color: TangemBadg
TangemBadgeColor.Gray -> TangemTheme.colors2.markers.backgroundSolidGray
TangemBadgeColor.Blue -> TangemTheme.colors2.markers.backgroundSolidBlue
TangemBadgeColor.Red -> TangemTheme.colors2.markers.backgroundSolidRed
TangemBadgeColor.Green -> TangemTheme.colors2.markers.backgroundSolidGreen
},
)
TangemBadgeType.Tinted -> background(
@ -293,6 +317,7 @@ private fun Modifier.getBackgroundColor(type: TangemBadgeType, color: TangemBadg
TangemBadgeColor.Gray -> TangemTheme.colors2.markers.backgroundTintedGray
TangemBadgeColor.Blue -> TangemTheme.colors2.markers.backgroundTintedBlue
TangemBadgeColor.Red -> TangemTheme.colors2.markers.backgroundTintedRed
TangemBadgeColor.Green -> TangemTheme.colors2.markers.backgroundTintedGreen
},
)
TangemBadgeType.Outline -> {
@ -301,6 +326,7 @@ private fun Modifier.getBackgroundColor(type: TangemBadgeType, color: TangemBadg
TangemBadgeColor.Gray -> TangemTheme.colors2.markers.borderGray
TangemBadgeColor.Blue -> TangemTheme.colors2.markers.borderTintedBlue
TangemBadgeColor.Red -> TangemTheme.colors2.markers.borderTintedRed
TangemBadgeColor.Green -> TangemTheme.colors2.markers.borderTintedGreen
},
shape = shape,
width = 1.dp,
@ -320,16 +346,16 @@ private fun TangemBadge_Preview(@PreviewParameter(TangemBadgePreviewProvider::cl
.background(TangemTheme.colors2.surface.level1)
.padding(8.dp),
) {
repeat(2) { yIndex ->
repeat(3) { yIndex ->
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
repeat(TangemBadgeType.entries.size) { index ->
TangemBadge(
text = stringReference("Title"),
text = stringReference("Title").takeIf { yIndex < 2 },
iconRes = R.drawable.ic_information_24,
type = TangemBadgeType.entries[index],
color = params,
shape = TangemBadgeShape.entries[yIndex % 2],
iconPosition = TangemBadgeIconPosition.entries[yIndex % 2],
iconPosition = TangemBadgeIconPosition.entries[yIndex],
)
}
}
@ -344,6 +370,7 @@ private class TangemBadgePreviewProvider : PreviewParameterProvider<TangemBadgeC
TangemBadgeColor.Gray,
TangemBadgeColor.Blue,
TangemBadgeColor.Red,
TangemBadgeColor.Green,
)
}
// endregion

View file

@ -16,8 +16,8 @@ import kotlin.math.max
/**
* A custom layout composable that arranges its children in a row with specific layout IDs.
*/
enum class TangemRowLayoutId {
HEAD, START_TOP, END_TOP, START_BOTTOM, END_BOTTOM, TAIL, EXTRA_TOP
internal enum class TangemRowLayoutId {
HEAD, START_TOP, END_TOP, START_BOTTOM, END_BOTTOM, TAIL, EXTRA_TOP, EXTRA_BOTTOM
}
/**
@ -37,6 +37,7 @@ fun TangemRowContainer(
val density = LocalDensity.current
val localDirection = LocalLayoutDirection.current
val verticalPadding = with(density) { TangemTheme.dimens2.x1.roundToPx() }
val extraContentPadding = with(density) { TangemTheme.dimens2.x2.roundToPx() }
val contentTopPadding = with(density) { contentPadding.calculateTopPadding().roundToPx() }
val contentBottomPadding = with(density) { contentPadding.calculateBottomPadding().roundToPx() }
val contentStartPadding = with(density) { contentPadding.calculateLeftPadding(localDirection).roundToPx() }
@ -110,6 +111,10 @@ fun TangemRowContainer(
layoutId = TangemRowLayoutId.EXTRA_TOP,
constraints = constraints,
)
val extraBottomPlaceable = measurables.measure(
layoutId = TangemRowLayoutId.EXTRA_BOTTOM,
constraints = constraints,
)
val mainLayoutHeight = maxOf(
headPlaceable.heightOrZero(),
@ -124,7 +129,13 @@ fun TangemRowContainer(
contentTopPadding
}
val layoutHeight = mainLayoutHeight + mainContentTopPadding + contentBottomPadding
val mainContentBottomPadding = if (extraBottomPlaceable != null) {
extraBottomPlaceable.heightOrZero() + contentBottomPadding
} else {
contentBottomPadding
}
val layoutHeight = mainLayoutHeight + mainContentTopPadding + mainContentBottomPadding
layout(width = constraints.maxWidth, height = layoutHeight) {
extraTopPlaceable?.placeRelative(x = 0, y = 0)
@ -174,6 +185,11 @@ fun TangemRowContainer(
x = layoutWidth - tailPlaceable.width + contentEndPadding,
y = mainContentTopPadding + (mainLayoutHeight - tailPlaceable.height).div(other = 2),
)
extraBottomPlaceable?.placeRelative(
x = 0,
y = mainContentTopPadding + mainLayoutHeight + extraContentPadding,
)
}
}
}

View file

@ -52,15 +52,6 @@ fun TangemTokenRow(
.testTag(tag = TokenElementsTestTags.TOKEN_ICON),
)
TokenRowPromoBanner(
promoBannerUM = tokenRowUM.promoBannerUM,
modifier = Modifier
.layoutId(layoutId = TangemRowLayoutId.EXTRA_TOP)
.testTag(tag = TokenElementsTestTags.TOKEN_YIELD_PROMO_BANNER)
.padding(horizontal = TangemTheme.dimens2.x3)
.fillMaxWidth(),
)
TokenRowTitle(
titleUM = tokenRowUM.titleUM,
modifier = Modifier
@ -77,17 +68,21 @@ fun TangemTokenRow(
.testTag(tag = TokenElementsTestTags.TOKEN_PRICE),
)
TokenRowEndTopContent(
TokenRowEndContent(
endContentUM = tokenRowUM.topEndContentUM,
isBalanceHidden = isBalanceHidden,
textStyle = TangemTheme.typography2.bodySemibold16,
textColor = TangemTheme.colors2.text.neutral.primary,
modifier = Modifier
.layoutId(layoutId = TangemRowLayoutId.END_TOP)
.testTag(tag = TokenElementsTestTags.TOKEN_FIAT_AMOUNT),
)
TokenRowEndBottomContent(
TokenRowEndContent(
endContentUM = tokenRowUM.bottomEndContentUM,
isBalanceHidden = isBalanceHidden,
textStyle = TangemTheme.typography2.captionSemibold12,
textColor = TangemTheme.colors2.text.neutral.secondary,
modifier = Modifier
.layoutId(layoutId = TangemRowLayoutId.END_BOTTOM)
.testTag(tag = TokenElementsTestTags.TOKEN_CRYPTO_AMOUNT),
@ -100,6 +95,15 @@ fun TangemTokenRow(
.layoutId(layoutId = TangemRowLayoutId.TAIL)
.testTag(tag = TokenElementsTestTags.TOKEN_NON_FIAT_BLOCK),
)
TokenRowPromoBanner(
promoBannerUM = tokenRowUM.promoBannerUM,
modifier = Modifier
.layoutId(layoutId = TangemRowLayoutId.EXTRA_BOTTOM)
.testTag(tag = TokenElementsTestTags.TOKEN_YIELD_PROMO_BANNER)
.padding(start = TangemTheme.dimens2.x10, bottom = TangemTheme.dimens2.x2)
.fillMaxWidth(),
)
},
modifier = modifier.tokenClickable(tokenRowUM = tokenRowUM),
)
@ -159,17 +163,21 @@ fun TangemTokenRow(
.testTag(tag = TokenElementsTestTags.TOKEN_PRICE),
)
TokenRowEndTopContent(
TokenRowEndContent(
endContentUM = tokenRowUM.topEndContentUM,
isBalanceHidden = isBalanceHidden,
textStyle = TangemTheme.typography2.bodySemibold16,
textColor = TangemTheme.colors2.text.neutral.primary,
modifier = Modifier
.layoutId(layoutId = TangemRowLayoutId.END_TOP)
.testTag(tag = TokenElementsTestTags.TOKEN_FIAT_AMOUNT),
)
TokenRowEndBottomContent(
TokenRowEndContent(
endContentUM = tokenRowUM.bottomEndContentUM,
isBalanceHidden = isBalanceHidden,
textStyle = TangemTheme.typography2.captionSemibold12,
textColor = TangemTheme.colors2.text.neutral.secondary,
modifier = Modifier
.layoutId(layoutId = TangemRowLayoutId.END_BOTTOM)
.testTag(tag = TokenElementsTestTags.TOKEN_CRYPTO_AMOUNT),

View file

@ -133,7 +133,8 @@ sealed class TangemTokenRowUM : TangemRowUM {
val text: TextReference,
val isAvailable: Boolean = true,
val isFlickering: Boolean = false,
val icons: ImmutableList<TangemIconUM.Icon> = persistentListOf(),
val startIcons: ImmutableList<TangemIconUM.Icon> = persistentListOf(),
val endIcons: ImmutableList<TangemIconUM.Icon> = persistentListOf(),
val priceChangeUM: PriceChangeState = PriceChangeState.Unknown,
) : EndContentUM()

View file

@ -142,7 +142,7 @@ internal object TangemTokenRowPreviewData {
)
}),
),
icons = persistentListOf(
startIcons = persistentListOf(
TangemIconUM.Icon(R.drawable.ic_staking_mini_10),
TangemIconUM.Icon(R.drawable.ic_attention_12),
TangemIconUM.Icon(R.drawable.ic_error_sync_24),

View file

@ -1,100 +0,0 @@
package com.tangem.core.ui.ds.row.token.internal
import android.content.res.Configuration
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.tangem.core.ui.components.TextShimmer
import com.tangem.core.ui.components.marketprice.PriceChangeState
import com.tangem.core.ui.components.text.applyBladeBrush
import com.tangem.core.ui.ds.row.token.TangemTokenRowUM
import com.tangem.core.ui.extensions.orMaskWithStars
import com.tangem.core.ui.extensions.resolveAnnotatedReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
@Composable
internal fun TokenRowEndBottomContent(
endContentUM: TangemTokenRowUM.EndContentUM,
isBalanceHidden: Boolean,
modifier: Modifier = Modifier,
) {
when (endContentUM) {
is TangemTokenRowUM.EndContentUM.Content -> Content(
modifier = modifier,
endContentUM = endContentUM,
isBalanceHidden = isBalanceHidden,
)
TangemTokenRowUM.EndContentUM.Empty -> Unit
TangemTokenRowUM.EndContentUM.Loading -> TextShimmer(
style = TangemTheme.typography2.captionSemibold12,
modifier = modifier.width(TangemTheme.dimens2.x10),
radius = TangemTheme.dimens2.x25,
)
}
}
@Composable
private fun Content(
endContentUM: TangemTokenRowUM.EndContentUM.Content,
isBalanceHidden: Boolean,
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = endContentUM.text.orMaskWithStars(isBalanceHidden).resolveAnnotatedReference(),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = TangemTheme.typography2.captionSemibold12.applyBladeBrush(
isEnabled = endContentUM.isFlickering,
textColor = if (endContentUM.isAvailable) {
TangemTheme.colors2.text.neutral.secondary
} else {
TangemTheme.colors2.text.status.disabled
},
),
)
when (val priceChangeUM = endContentUM.priceChangeUM) {
is PriceChangeState.Content -> TokenRowPriceChangeContent(
priceChangeState = priceChangeUM,
isFlickering = endContentUM.isFlickering,
isAvailable = endContentUM.isAvailable,
)
PriceChangeState.Unknown -> Unit
}
}
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun TokenRowEndBottomContent_Preview(
@PreviewParameter(TokenRowEndBottomContentPreviewProvider::class) params: TangemTokenRowUM.EndContentUM,
) {
TangemThemePreviewRedesign {
TokenRowEndBottomContent(
endContentUM = params,
isBalanceHidden = false,
)
}
}
private class TokenRowEndBottomContentPreviewProvider : PreviewParameterProvider<TangemTokenRowUM.EndContentUM> {
override val values: Sequence<TangemTokenRowUM.EndContentUM>
get() = sequenceOf(
TangemTokenRowPreviewData.bottomEndContentUM,
)
}
// endregion

View file

@ -8,15 +8,18 @@ import androidx.compose.material3.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.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.util.fastForEach
import com.tangem.core.ui.components.TextShimmer
import com.tangem.core.ui.components.marketprice.PriceChangeState
import com.tangem.core.ui.components.text.applyBladeBrush
import com.tangem.core.ui.ds.row.token.TangemTokenRowUM
import com.tangem.core.ui.extensions.orMaskWithStars
@ -25,9 +28,11 @@ import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
@Composable
internal fun TokenRowEndTopContent(
internal fun TokenRowEndContent(
endContentUM: TangemTokenRowUM.EndContentUM,
isBalanceHidden: Boolean,
textStyle: TextStyle,
textColor: Color,
modifier: Modifier = Modifier,
) {
when (endContentUM) {
@ -35,11 +40,13 @@ internal fun TokenRowEndTopContent(
modifier = modifier,
endContentUM = endContentUM,
isBalanceHidden = isBalanceHidden,
textStyle = textStyle,
textColor = textColor,
)
TangemTokenRowUM.EndContentUM.Empty -> Unit
TangemTokenRowUM.EndContentUM.Loading -> TextShimmer(
style = TangemTheme.typography2.bodySemibold16,
modifier = modifier.width(TangemTheme.dimens2.x18),
style = textStyle,
modifier = modifier.width(TangemTheme.dimens2.x10),
radius = TangemTheme.dimens2.x25,
)
}
@ -48,6 +55,8 @@ internal fun TokenRowEndTopContent(
@Composable
private fun Content(
endContentUM: TangemTokenRowUM.EndContentUM.Content,
textStyle: TextStyle,
textColor: Color,
isBalanceHidden: Boolean,
modifier: Modifier = Modifier,
) {
@ -56,14 +65,14 @@ private fun Content(
verticalAlignment = Alignment.CenterVertically,
) {
AnimatedVisibility(
visible = endContentUM.icons.isNotEmpty(),
visible = endContentUM.startIcons.isNotEmpty(),
) {
Row(
modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x1),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
) {
endContentUM.icons.fastForEach { icon ->
endContentUM.startIcons.fastForEach { icon ->
Icon(
modifier = Modifier.size(TangemTheme.dimens2.x3),
painter = rememberVectorPainter(image = ImageVector.vectorResource(icon.iconRes)),
@ -75,11 +84,11 @@ private fun Content(
}
Text(
modifier = Modifier,
text = endContentUM.text.orMaskWithStars(isBalanceHidden).resolveAnnotatedReference(),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = TangemTheme.typography2.bodySemibold16.applyBladeBrush(
color = textColor,
style = textStyle.applyBladeBrush(
isEnabled = endContentUM.isFlickering,
textColor = if (endContentUM.isAvailable) {
TangemTheme.colors2.text.neutral.primary
@ -88,6 +97,34 @@ private fun Content(
},
),
)
AnimatedVisibility(
visible = endContentUM.endIcons.isNotEmpty(),
) {
Row(
modifier = Modifier.padding(start = TangemTheme.dimens2.x0_5),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
) {
endContentUM.endIcons.fastForEach { icon ->
Icon(
modifier = Modifier.size(TangemTheme.dimens2.x3),
painter = rememberVectorPainter(image = ImageVector.vectorResource(icon.iconRes)),
tint = icon.tintReference(),
contentDescription = null,
)
}
}
}
when (val priceChangeUM = endContentUM.priceChangeUM) {
is PriceChangeState.Content -> TokenRowPriceChangeContent(
priceChangeState = priceChangeUM,
isFlickering = endContentUM.isFlickering,
isAvailable = endContentUM.isAvailable,
)
PriceChangeState.Unknown -> Unit
}
}
}
@ -95,13 +132,15 @@ private fun Content(
@Composable
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun TokenRowEndTopContent_Preview(
private fun TokenRowEndContent_Preview(
@PreviewParameter(TokenRowEndContentPreviewProvider::class) params: TangemTokenRowUM.EndContentUM,
) {
TangemThemePreviewRedesign {
TokenRowEndTopContent(
TokenRowEndContent(
endContentUM = params,
isBalanceHidden = false,
textColor = TangemTheme.colors2.text.neutral.primary,
textStyle = TangemTheme.typography2.captionSemibold12,
)
}
}
@ -109,7 +148,7 @@ private fun TokenRowEndTopContent_Preview(
private class TokenRowEndContentPreviewProvider : PreviewParameterProvider<TangemTokenRowUM.EndContentUM> {
override val values: Sequence<TangemTokenRowUM.EndContentUM>
get() = sequenceOf(
TangemTokenRowPreviewData.topEndContentUM,
TangemTokenRowPreviewData.bottomEndContentUM,
)
}
// endregion

View file

@ -3,15 +3,12 @@ package com.tangem.core.ui.ds.row.token.internal
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
@ -19,6 +16,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.R
import com.tangem.core.ui.ds.badge.*
import com.tangem.core.ui.ds.row.token.TangemTokenRowUM
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
@ -40,55 +38,52 @@ internal fun TokenRowPromoBanner(promoBannerUM: TangemTokenRowUM.PromoBannerUM.C
LaunchedEffect(promoBannerUM) {
promoBannerUM.onPromoShown()
}
val bgColor = TangemTheme.colors.control.default
Column(modifier = modifier) {
val bgColor = TangemTheme.colors2.markers.backgroundTintedGreen
Column(
modifier = modifier,
) {
Icon(
painter = painterResource(id = R.drawable.shape_triangular),
contentDescription = null,
tint = bgColor,
modifier = Modifier.padding(start = TangemTheme.dimens2.x5),
)
Row(
modifier = Modifier
.background(color = bgColor, shape = RoundedCornerShape(TangemTheme.dimens2.x4))
.clickable(onClick = promoBannerUM.onPromoBannerClick)
.padding(horizontal = TangemTheme.dimens2.x3, vertical = TangemTheme.dimens2.x2)
.fillMaxWidth(),
.padding(
start = TangemTheme.dimens2.x2_5,
end = TangemTheme.dimens2.x0_5,
top = TangemTheme.dimens2.x0_5,
bottom = TangemTheme.dimens2.x0_5,
),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
) {
Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.ic_analytics_up_24),
contentDescription = null,
tint = TangemTheme.colors.icon.accent,
tint = TangemTheme.colors2.markers.textGreen,
modifier = Modifier
.padding(end = TangemTheme.dimens2.x2)
.size(TangemTheme.dimens2.x4),
.padding(vertical = TangemTheme.dimens2.x0_5)
.size(TangemTheme.dimens2.x3),
)
Text(
text = promoBannerUM.title.resolveReference(),
style = TangemTheme.typography2.captionSemibold12,
color = TangemTheme.colors2.text.neutral.secondary,
style = TangemTheme.typography2.captionSemibold11,
color = TangemTheme.colors2.markers.textGreen,
modifier = Modifier
.weight(1f)
.padding(end = TangemTheme.dimens2.x2),
.padding(vertical = TangemTheme.dimens2.x0_5),
)
Icon(
painter = painterResource(id = R.drawable.ic_close_24),
contentDescription = null,
tint = TangemTheme.colors2.text.neutral.secondary,
modifier = Modifier
.size(TangemTheme.dimens2.x4)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = ripple(bounded = false),
onClick = { promoBannerUM.onCloseClick() },
),
)
}
Box(
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.Center,
) {
Icon(
painter = painterResource(id = R.drawable.ic_rectangle_bottom),
contentDescription = null,
tint = bgColor,
modifier = Modifier
.size(width = TangemTheme.dimens2.x3, height = TangemTheme.dimens2.x2),
TangemBadge(
size = TangemBadgeSize.X4,
shape = TangemBadgeShape.Rounded,
color = TangemBadgeColor.Green,
type = TangemBadgeType.Tinted,
iconRes = R.drawable.ic_close_24,
iconPosition = TangemBadgeIconPosition.None,
onClick = promoBannerUM.onCloseClick,
)
}
}

View file

@ -59,20 +59,45 @@ object TangemColorPalette {
val DarkGreen = Color(0xFF06311F)
// endregion Green
// region Blue
// region Azure
val Azure = Color(0xFF0099FF)
val Azure_50 = Color(0x800099FF)
val Azure_10 = Color(0x1A0099FF)
// endregion Blue
// region Red
// region Amaranth
val Amaranth = Color(0xFFFF3333)
val Amaranth_50 = Color(0x80FF3333)
val Amaranth_20 = Color(0x33FF3333)
val Amaranth_10 = Color(0x1AFF3333)
// endregion Amaranth
// region Flamingo
val Flamingo = Color(0xFFFF5B5B)
// endregion Red
val Flamingo_50 = Color(0x80FF5B5B)
val Flamingo_20 = Color(0x33FF5B5B)
val Flamingo_10 = Color(0x1AFF5B5B)
// endregion Flamingo
// region Yellow
val Tangerine = Color(0xFFFFB71B)
val Mustard = Color(0xFFFDDE55)
// endregion Yellow
// region Emerald
val Emerald = Color(0xFF34DF12)
val Emerald_50 = Color(0x8034DF12)
val Emerald_20 = Color(0x3334DF12)
val Emerald_10 = Color(0x1A34DF12)
// endregion Emerald
// region Eucalyptus
val Eucalyptus = Color(0xFF0C9F3D)
val Eucalyptus_50 = Color(0x800C9F3D)
val Eucalyptus_20 = Color(0x330C9F3D)
val Eucalyptus_10 = Color(0x1A0C9F3D)
// endregion Emerald
// region Overlay
val Overlay1 = Color(0x66000000)
val Overlay2 = Color(0xB2000000)

View file

@ -448,24 +448,36 @@ class TangemColors2 internal constructor(
@Stable
class Markers internal constructor(
backgroundSolidGray: Color,
backgroundDisabled: Color,
backgroundSolidBlue: Color,
textGray: Color,
textDisabled: Color,
iconGray: Color,
iconDisabled: Color,
backgroundDisabled: Color,
textGray: Color,
iconGray: Color,
borderGray: Color,
backgroundTintedBlue: Color,
backgroundSolidGray: Color,
backgroundTintedGray: Color,
textBlue: Color,
iconBlue: Color,
borderTintedBlue: Color,
backgroundSolidBlue: Color,
backgroundTintedBlue: Color,
textRed: Color,
iconRed: Color,
borderTintedRed: Color,
backgroundSolidRed: Color,
backgroundTintedRed: Color,
iconBlue: Color,
iconRed: Color,
textRed: Color,
backgroundTintedGray: Color,
borderTintedBlue: Color,
borderTintedRed: Color,
textGreen: Color,
iconGreen: Color,
borderTintedGreen: Color,
borderSolidColor: Color,
backgroundTintedGreen: Color,
backgroundSolidGreen: Color,
textGreenAlt: Color,
iconGreenAlt: Color,
borderTintedGreenAlt: Color,
borderSolidColorAlt: Color,
backgroundTintedGreenAlt: Color,
backgroundSolidGreenAlt: Color,
) {
var backgroundSolidGray by mutableStateOf(backgroundSolidGray)
private set
@ -504,6 +516,32 @@ class TangemColors2 internal constructor(
var borderTintedRed by mutableStateOf(borderTintedRed)
private set
var textGreen by mutableStateOf(textGreen)
private set
var iconGreen by mutableStateOf(iconGreen)
private set
var borderTintedGreen by mutableStateOf(borderTintedGreen)
private set
var borderSolidColor by mutableStateOf(borderSolidColor)
private set
var backgroundTintedGreen by mutableStateOf(backgroundTintedGreen)
private set
var backgroundSolidGreen by mutableStateOf(backgroundSolidGreen)
private set
var textGreenAlt by mutableStateOf(textGreenAlt)
private set
var iconGreenAlt by mutableStateOf(iconGreenAlt)
private set
var borderTintedGreenAlt by mutableStateOf(borderTintedGreenAlt)
private set
var borderSolidColorAlt by mutableStateOf(borderSolidColorAlt)
private set
var backgroundTintedGreenAlt by mutableStateOf(backgroundTintedGreen)
private set
var backgroundSolidGreenAlt by mutableStateOf(backgroundSolidGreen)
private set
fun update(other: Markers) {
backgroundSolidGray = other.backgroundSolidGray
backgroundDisabled = other.backgroundDisabled
@ -523,6 +561,18 @@ class TangemColors2 internal constructor(
backgroundTintedGray = other.backgroundTintedGray
borderTintedBlue = other.borderTintedBlue
borderTintedRed = other.borderTintedRed
textGreen = other.textGreen
iconGreen = other.iconGreen
borderTintedGreen = other.borderTintedGreen
borderSolidColor = other.borderSolidColor
backgroundTintedGreen = other.backgroundTintedGreen
backgroundSolidGreen = other.backgroundSolidGreen
textGreenAlt = other.textGreenAlt
iconGreenAlt = other.iconGreenAlt
borderTintedGreenAlt = other.borderTintedGreenAlt
borderSolidColorAlt = other.borderSolidColorAlt
backgroundTintedGreenAlt = other.backgroundTintedGreenAlt
backgroundSolidGreenAlt = other.backgroundSolidGreenAlt
}
}

View file

@ -154,16 +154,28 @@ private fun lightThemeColors2(): TangemColors2 {
iconGray = TangemColorPalette.Dark1,
iconDisabled = TangemColorPalette.Light2,
borderGray = TangemColorPalette.Light3,
backgroundTintedBlue = TangemColorPalette.Azure.copy(alpha = 0.1f),
backgroundTintedBlue = TangemColorPalette.Azure_10,
textBlue = text.status.accent,
backgroundSolidRed = TangemColorPalette.Amaranth,
backgroundTintedRed = TangemColorPalette.Amaranth.copy(alpha = 0.1f),
backgroundTintedRed = TangemColorPalette.Amaranth_10,
iconBlue = TangemColorPalette.Azure,
iconRed = TangemColorPalette.Amaranth,
textRed = TangemColorPalette.Amaranth,
backgroundTintedGray = TangemColorPalette.Dark6.copy(alpha = 0.1f),
borderTintedBlue = TangemColorPalette.Azure.copy(alpha = 0.1f),
borderTintedRed = TangemColorPalette.Amaranth.copy(alpha = 0.1f),
borderTintedBlue = TangemColorPalette.Azure_10,
borderTintedRed = TangemColorPalette.Amaranth_10,
textGreen = TangemColorPalette.Emerald,
iconGreen = TangemColorPalette.Emerald,
borderTintedGreen = TangemColorPalette.Emerald_10,
borderSolidColor = TangemColorPalette.Emerald_50,
backgroundTintedGreen = TangemColorPalette.Emerald_10,
backgroundSolidGreen = TangemColorPalette.Emerald,
textGreenAlt = TangemColorPalette.Eucalyptus,
iconGreenAlt = TangemColorPalette.Eucalyptus,
borderTintedGreenAlt = TangemColorPalette.Eucalyptus_10,
borderSolidColorAlt = TangemColorPalette.Eucalyptus_50,
backgroundTintedGreenAlt = TangemColorPalette.Eucalyptus_10,
backgroundSolidGreenAlt = TangemColorPalette.Eucalyptus,
)
val tabs = TangemColors2.Tabs(
textPrimary = TangemColorPalette.Light2,
@ -304,7 +316,7 @@ private fun darkThemeColors2(): TangemColors2 {
iconGray = TangemColorPalette.Dark2,
iconDisabled = TangemColorPalette.Dark5,
borderGray = TangemColorPalette.White.copy(alpha = 0.2f),
backgroundTintedBlue = TangemColorPalette.Azure.copy(alpha = 0.1f),
backgroundTintedBlue = TangemColorPalette.Azure_10,
textBlue = text.status.accent,
backgroundSolidRed = TangemColorPalette.Amaranth,
backgroundTintedRed = TangemColorPalette.Amaranth.copy(alpha = 0.1f),
@ -312,8 +324,20 @@ private fun darkThemeColors2(): TangemColors2 {
iconRed = TangemColorPalette.Flamingo,
textRed = TangemColorPalette.Flamingo,
backgroundTintedGray = TangemColorPalette.White.copy(alpha = 0.1f),
borderTintedBlue = TangemColorPalette.Azure.copy(alpha = 0.1f),
borderTintedRed = TangemColorPalette.Amaranth.copy(alpha = 0.1f),
borderTintedBlue = TangemColorPalette.Azure_10,
borderTintedRed = TangemColorPalette.Amaranth_10,
textGreen = TangemColorPalette.Emerald,
iconGreen = TangemColorPalette.Emerald,
borderTintedGreen = TangemColorPalette.Emerald_10,
borderSolidColor = TangemColorPalette.Emerald_50,
backgroundTintedGreen = TangemColorPalette.Emerald_10,
backgroundSolidGreen = TangemColorPalette.Emerald,
textGreenAlt = TangemColorPalette.Emerald,
iconGreenAlt = TangemColorPalette.Emerald,
borderTintedGreenAlt = TangemColorPalette.Emerald_10,
borderSolidColorAlt = TangemColorPalette.Emerald_50,
backgroundTintedGreenAlt = TangemColorPalette.Emerald_10,
backgroundSolidGreenAlt = TangemColorPalette.Emerald,
)
val tabs = TangemColors2.Tabs(
textPrimary = TangemColorPalette.Dark4,

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="8dp"
android:viewportWidth="8"
android:viewportHeight="8">
<path
android:fillColor="#34DF12"
android:pathData="M8,8L0,8L0,0C0,0 2,6 8,8Z" />
</vector>