diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabel.kt b/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabel.kt
index eed177c971..e5293e07ab 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabel.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabel.kt
@@ -2,6 +2,7 @@ package com.tangem.core.ui.components.audits
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -11,6 +12,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
+import androidx.compose.ui.unit.dp
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
@@ -30,41 +32,59 @@ import com.tangem.core.ui.res.TangemThemePreview
fun AuditLabel(state: AuditLabelUM, modifier: Modifier = Modifier) {
AuditLabelInternal(
textReference = state.text,
- textColor = getColorByType(state.type),
- backgroundColor = getColorByType(state.type).copy(alpha = 0.1f),
+ type = state.type,
modifier = modifier,
)
}
@Composable
-private fun AuditLabelInternal(
- textReference: TextReference,
- textColor: Color,
- backgroundColor: Color,
- modifier: Modifier = Modifier,
-) {
+private fun AuditLabelInternal(textReference: TextReference, type: AuditLabelUM.Type, modifier: Modifier = Modifier) {
Box(
modifier = modifier.background(
- color = backgroundColor,
+ color = getBackgroundColorByType(type),
shape = TangemTheme.shapes.roundedCornersSmall2,
),
) {
Text(
text = textReference.resolveReference(),
style = TangemTheme.typography.caption1,
- color = textColor,
- modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing4),
+ color = getTextColorByType(type),
+ modifier = Modifier.padding(getPaddingByType(type)),
)
}
}
@ReadOnlyComposable
@Composable
-private fun getColorByType(type: AuditLabelUM.Type): Color {
+private fun getTextColorByType(type: AuditLabelUM.Type): Color {
return when (type) {
AuditLabelUM.Type.Prohibition -> TangemTheme.colors.text.warning
AuditLabelUM.Type.Warning -> TangemTheme.colors.text.attention
AuditLabelUM.Type.Permit -> TangemTheme.colors.text.accent
+ AuditLabelUM.Type.Info -> TangemTheme.colors.text.primary2
+ }
+}
+
+@ReadOnlyComposable
+@Composable
+private fun getBackgroundColorByType(type: AuditLabelUM.Type): Color {
+ return when (type) {
+ AuditLabelUM.Type.Prohibition -> TangemTheme.colors.text.warning.copy(alpha = 0.1f)
+ AuditLabelUM.Type.Warning -> TangemTheme.colors.text.attention.copy(alpha = 0.1f)
+ AuditLabelUM.Type.Permit -> TangemTheme.colors.text.accent.copy(alpha = 0.1f)
+ AuditLabelUM.Type.Info -> TangemTheme.colors.text.accent
+ }
+}
+
+@ReadOnlyComposable
+@Composable
+private fun getPaddingByType(type: AuditLabelUM.Type): PaddingValues {
+ return when (type) {
+ AuditLabelUM.Type.Prohibition,
+ AuditLabelUM.Type.Warning,
+ AuditLabelUM.Type.Permit,
+ -> PaddingValues(horizontal = 4.dp)
+ AuditLabelUM.Type.Info -> PaddingValues(horizontal = 6.dp, vertical = 1.dp)
}
}
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabelUM.kt b/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabelUM.kt
index 25059b9594..4b1ed19772 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabelUM.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/audits/AuditLabelUM.kt
@@ -22,5 +22,8 @@ data class AuditLabelUM(val text: TextReference, val type: Type) {
/** Blue. Like, "trusted" */
Permit,
+
+ /** Blue with white text. Like, "best rate" */
+ Info,
}
}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/badge/Badge.kt b/core/ui/src/main/java/com/tangem/core/ui/components/badge/Badge.kt
new file mode 100644
index 0000000000..282f4a0618
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/badge/Badge.kt
@@ -0,0 +1,74 @@
+package com.tangem.core.ui.components.badge
+
+import android.content.res.Configuration
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+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.vector.ImageVector
+import androidx.compose.ui.graphics.vector.rememberVectorPainter
+import androidx.compose.ui.res.vectorResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.tangem.core.ui.R
+import com.tangem.core.ui.extensions.TextReference
+import com.tangem.core.ui.extensions.resolveReference
+import com.tangem.core.ui.extensions.stringReference
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+
+/**
+ * Badge component
+ *
+ * @param iconRes icon drawable resource
+ * @param text text reference
+ * @param modifier composable modifier
+ *
+ * @see Figma
+ */
+@Composable
+fun Badge(@DrawableRes iconRes: Int, text: TextReference, modifier: Modifier = Modifier) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(4.dp),
+ modifier = modifier
+ .border(1.dp, TangemTheme.colors.stroke.primary, RoundedCornerShape(4.dp))
+ .padding(horizontal = 4.dp),
+ ) {
+ Icon(
+ painter = rememberVectorPainter(
+ ImageVector.vectorResource(iconRes),
+ ),
+ contentDescription = null,
+ tint = TangemTheme.colors.icon.informative,
+ modifier = Modifier.size(12.dp),
+ )
+ Text(
+ text = text.resolveReference(),
+ style = TangemTheme.typography.caption2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ }
+}
+
+// region Preview
+@Composable
+@Preview(showBackground = true, widthDp = 360)
+@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
+private fun Badge_Preview() {
+ TangemThemePreview {
+ Badge(
+ iconRes = R.drawable.ic_star_mini_24,
+ text = stringReference("4.9"),
+ )
+ }
+}
+// endregion
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/badge/entity/BadgeUM.kt b/core/ui/src/main/java/com/tangem/core/ui/components/badge/entity/BadgeUM.kt
new file mode 100644
index 0000000000..ee6aa0bcdb
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/badge/entity/BadgeUM.kt
@@ -0,0 +1,15 @@
+package com.tangem.core.ui.components.badge.entity
+
+import androidx.annotation.DrawableRes
+import com.tangem.core.ui.extensions.TextReference
+
+/**
+ * Badge component UI model
+ *
+ * @param iconRes icon drawable resource
+ * @param text text reference
+ */
+data class BadgeUM(
+ val text: TextReference,
+ @DrawableRes val iconRes: Int,
+)
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonSize.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonSize.kt
index 961bca8869..46530d78b1 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonSize.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonSize.kt
@@ -16,6 +16,7 @@ enum class TangemButtonSize {
RoundedAction,
WideAction,
TwoLines,
+ Small,
}
@Composable
@@ -28,6 +29,7 @@ internal fun TangemButtonSize.toHeightDp(): Dp = when (this) {
TangemButtonSize.RoundedAction,
-> TangemTheme.dimens.size36
TangemButtonSize.WideAction -> TangemTheme.dimens.size40
+ TangemButtonSize.Small -> 24.dp
}
@Composable
@@ -40,6 +42,7 @@ internal fun TangemButtonSize.toShape(): Shape = when (this) {
TangemButtonSize.Action -> TangemTheme.shapes.roundedCornersMedium
TangemButtonSize.TwoLines -> TangemTheme.shapes.roundedCornersXMedium
TangemButtonSize.RoundedAction -> TangemTheme.shapes.roundedCornersLarge
+ TangemButtonSize.Small -> TangemTheme.shapes.roundedCornersXMedium
}
@Composable
@@ -48,6 +51,7 @@ internal fun TangemButtonSize.toIconPadding(): Dp = when (this) {
TangemButtonSize.Default,
TangemButtonSize.WideAction,
TangemButtonSize.TwoLines,
+ TangemButtonSize.Small,
-> TangemTheme.dimens.spacing4
TangemButtonSize.Text -> TangemTheme.dimens.spacing8
TangemButtonSize.Selector -> 0.dp
@@ -100,11 +104,18 @@ internal fun TangemButtonSize.toContentPadding(icon: TangemButtonIconPosition):
start = horizontalPadding.first,
end = horizontalPadding.second,
)
+ TangemButtonSize.Small -> PaddingValues(
+ top = TangemTheme.dimens.spacing4,
+ bottom = TangemTheme.dimens.spacing4,
+ start = horizontalPadding.first,
+ end = horizontalPadding.second,
+ )
}
}
@Composable
@ReadOnlyComposable
+@Suppress("CyclomaticComplexMethod")
internal fun TangemButtonSize.toHorizontalContentPadding(icon: TangemButtonIconPosition): Pair {
return when (this) {
TangemButtonSize.Default,
@@ -124,5 +135,10 @@ internal fun TangemButtonSize.toHorizontalContentPadding(icon: TangemButtonIconP
is TangemButtonIconPosition.Start -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing24
is TangemButtonIconPosition.End -> TangemTheme.dimens.spacing24 to TangemTheme.dimens.spacing16
}
+ TangemButtonSize.Small -> when (icon) {
+ is TangemButtonIconPosition.None -> TangemTheme.dimens.spacing12 to TangemTheme.dimens.spacing12
+ is TangemButtonIconPosition.Start -> TangemTheme.dimens.spacing8 to TangemTheme.dimens.spacing12
+ is TangemButtonIconPosition.End -> TangemTheme.dimens.spacing12 to TangemTheme.dimens.spacing8
+ }
}
}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/provider/ProviderChooseCrypto.kt b/core/ui/src/main/java/com/tangem/core/ui/components/provider/ProviderChooseCrypto.kt
new file mode 100644
index 0000000000..1083b56912
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/provider/ProviderChooseCrypto.kt
@@ -0,0 +1,323 @@
+package com.tangem.core.ui.components.provider
+
+import android.content.res.Configuration
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.platform.LocalContext
+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.unit.dp
+import androidx.compose.ui.util.fastForEach
+import androidx.constraintlayout.compose.ConstraintLayout
+import androidx.constraintlayout.compose.Dimension
+import androidx.constraintlayout.compose.Visibility
+import coil.compose.SubcomposeAsyncImage
+import coil.request.ImageRequest
+import com.tangem.core.ui.R
+import com.tangem.core.ui.components.audits.AuditLabel
+import com.tangem.core.ui.components.audits.AuditLabelUM
+import com.tangem.core.ui.components.badge.Badge
+import com.tangem.core.ui.components.badge.entity.BadgeUM
+import com.tangem.core.ui.components.provider.entity.ProviderChooseUM
+import com.tangem.core.ui.extensions.*
+import com.tangem.core.ui.res.TangemColorPalette
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+import kotlinx.collections.immutable.persistentListOf
+
+/**
+ * Provider Row - Choose Crypto component
+ *
+ * @param providerChooseUM component ui model
+ * @param onClick click listener
+ * @param modifier composable modifier
+ *
+ * @see Figma
+ */
+@Composable
+@Suppress("DestructuringDeclarationWithTooManyEntries")
+fun ProviderChooseCrypto(providerChooseUM: ProviderChooseUM, onClick: () -> Unit, modifier: Modifier = Modifier) {
+ ConstraintLayout(
+ modifier = modifier
+ .background(TangemTheme.colors.background.action)
+ .clip(RoundedCornerShape(14.dp))
+ .selectedBorder(isSelected = providerChooseUM.isSelected)
+ .clickable(enabled = true, onClick = onClick)
+ .fillMaxWidth()
+ .padding(all = 12.dp),
+ ) {
+ val (iconRef, titleRef, badgeRef, infoRef, labelRef) = createRefs()
+ val titleEndRef = createStartBarrier(infoRef, labelRef)
+
+ IconContent(
+ iconUrl = providerChooseUM.iconUrl,
+ modifier = Modifier
+ .constrainAs(iconRef) {
+ start.linkTo(parent.start)
+ top.linkTo(parent.top)
+ bottom.linkTo(parent.bottom)
+ },
+ )
+ TitleContent(
+ providerChooseUM = providerChooseUM,
+ modifier = Modifier.constrainAs(titleRef) {
+ start.linkTo(iconRef.end, 12.dp)
+ end.linkTo(titleEndRef, 4.dp)
+ top.linkTo(parent.top)
+ bottom.linkTo(badgeRef.top)
+ width = Dimension.fillToConstraints
+ },
+ )
+ BadgeContent(
+ providerChooseUM = providerChooseUM,
+ modifier = Modifier.constrainAs(badgeRef) {
+ start.linkTo(iconRef.end, 12.dp)
+ end.linkTo(labelRef.start, 4.dp)
+ top.linkTo(titleRef.bottom, 4.dp)
+ bottom.linkTo(parent.bottom)
+ width = Dimension.fillToConstraints
+ visibility = if (providerChooseUM.badgeList.isEmpty()) {
+ Visibility.Gone
+ } else {
+ Visibility.Visible
+ }
+ },
+ )
+ InfoContent(
+ text = providerChooseUM.infoText,
+ modifier = Modifier.constrainAs(infoRef) {
+ end.linkTo(parent.end)
+ top.linkTo(parent.top)
+ bottom.linkTo(labelRef.top, 4.dp)
+ },
+ )
+ LabelContent(
+ labelUM = providerChooseUM.labelUM,
+ modifier = Modifier.constrainAs(labelRef) {
+ end.linkTo(parent.end)
+ top.linkTo(infoRef.bottom)
+ bottom.linkTo(parent.bottom)
+ visibility = if (providerChooseUM.labelUM == null) {
+ Visibility.Gone
+ } else {
+ Visibility.Visible
+ }
+ },
+ )
+ }
+}
+
+@Composable
+private fun IconContent(iconUrl: String, modifier: Modifier = Modifier) {
+ SubcomposeAsyncImage(
+ modifier = modifier
+ .size(40.dp)
+ .clip(RoundedCornerShape(8.dp))
+ .background(TangemColorPalette.Light1),
+ model = ImageRequest.Builder(context = LocalContext.current)
+ .data(iconUrl)
+ .crossfade(enable = true)
+ .allowHardware(false)
+ .build(),
+ contentDescription = null,
+ )
+}
+
+@Composable
+private fun TitleContent(providerChooseUM: ProviderChooseUM, modifier: Modifier = Modifier) {
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(4.dp),
+ modifier = modifier,
+ ) {
+ Text(
+ text = providerChooseUM.title.resolveReference(),
+ style = TangemTheme.typography.subtitle2,
+ color = TangemTheme.colors.text.primary1,
+ maxLines = 1,
+ )
+ Text(
+ text = providerChooseUM.subtitle.resolveReference(),
+ style = TangemTheme.typography.body2,
+ color = TangemTheme.colors.text.tertiary,
+ maxLines = 1,
+ )
+ }
+}
+
+@Composable
+private fun InfoContent(text: TextReference, modifier: Modifier = Modifier) {
+ Text(
+ text = text.resolveReference(),
+ style = TangemTheme.typography.body2,
+ color = TangemTheme.colors.text.primary1,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ modifier = modifier,
+ )
+}
+
+@Composable
+private fun BadgeContent(providerChooseUM: ProviderChooseUM, modifier: Modifier = Modifier) {
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(4.dp),
+ modifier = modifier,
+ ) {
+ providerChooseUM.badgeList.fastForEach { badge ->
+ Badge(
+ iconRes = badge.iconRes,
+ text = badge.text,
+ )
+ }
+ }
+}
+
+@Composable
+private fun LabelContent(labelUM: ProviderChooseUM.LabelUM?, modifier: Modifier = Modifier) {
+ Box(
+ modifier = modifier,
+ ) {
+ when (labelUM) {
+ is ProviderChooseUM.LabelUM.Info -> AuditLabel(labelUM.auditLabelUM)
+ is ProviderChooseUM.LabelUM.Text -> Text(
+ text = labelUM.text.resolveReference(),
+ style = TangemTheme.typography.caption2,
+ color = TangemTheme.colors.text.warning,
+ )
+ null -> Unit
+ }
+ }
+}
+
+// region Preview
+@Composable
+@Preview(showBackground = true, widthDp = 360)
+@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
+private fun ProviderChooseCrypto_Preview(
+ @PreviewParameter(ProviderChooseCryptoPreviewProvider::class) params: ProviderChooseUM,
+) {
+ TangemThemePreview {
+ ProviderChooseCrypto(
+ providerChooseUM = params,
+ onClick = {},
+ )
+ }
+}
+
+private class ProviderChooseCryptoPreviewProvider : PreviewParameterProvider {
+ override val values: Sequence
+ get() = sequenceOf(
+ ProviderChooseUM(
+ title = stringReference("ChangeHero"),
+ subtitle = stringReference("CEX"),
+ infoText = stringReference("1 800,00 POL"),
+ iconUrl = "",
+ badgeList = persistentListOf(
+ BadgeUM(
+ text = stringReference("4.9"),
+ iconRes = R.drawable.ic_star_outline_24,
+ ),
+ BadgeUM(
+ text = stringReference("5 mins"),
+ iconRes = R.drawable.ic_speed_24,
+ ),
+ BadgeUM(
+ text = stringReference("$3.45"),
+ iconRes = R.drawable.ic_gas_24,
+ ),
+ ),
+ isSelected = true,
+ labelUM = ProviderChooseUM.LabelUM.Info(
+ auditLabelUM = AuditLabelUM(
+ text = resourceReference(R.string.express_provider_best_rate),
+ type = AuditLabelUM.Type.Info,
+ ),
+ ),
+ ),
+ ProviderChooseUM(
+ title = stringReference("Changelly"),
+ subtitle = stringReference("CEX"),
+ infoText = stringReference("1 799,12 POL"),
+ iconUrl = "",
+ badgeList = persistentListOf(
+ BadgeUM(
+ text = stringReference("4.9"),
+ iconRes = R.drawable.ic_star_outline_24,
+ ),
+ BadgeUM(
+ text = stringReference("5 mins"),
+ iconRes = R.drawable.ic_speed_24,
+ ),
+ BadgeUM(
+ text = stringReference("$3.45"),
+ iconRes = R.drawable.ic_gas_24,
+ ),
+ ),
+ isSelected = false,
+ labelUM = ProviderChooseUM.LabelUM.Text(
+ text = stringReference("–0.2%"),
+ ),
+ ),
+ ProviderChooseUM(
+ title = stringReference("Changelly"),
+ subtitle = stringReference("CEX"),
+ infoText = stringReference("1 799,12 POL"),
+ iconUrl = "",
+ badgeList = persistentListOf(),
+ isSelected = false,
+ labelUM = ProviderChooseUM.LabelUM.Text(
+ text = stringReference("–0.2%"),
+ ),
+ ),
+ ProviderChooseUM(
+ title = stringReference("Changelly"),
+ subtitle = stringReference("CEX"),
+ infoText = stringReference("1 POL"),
+ iconUrl = "",
+ badgeList = persistentListOf(),
+ isSelected = false,
+ labelUM = ProviderChooseUM.LabelUM.Text(
+ text = stringReference("–0.2%"),
+ ),
+ ),
+ ProviderChooseUM(
+ title = stringReference("Changelly"),
+ subtitle = stringReference("CEX"),
+ infoText = stringReference("1 POL"),
+ iconUrl = "",
+ badgeList = persistentListOf(),
+ isSelected = false,
+ labelUM = null,
+ ),
+ ProviderChooseUM(
+ title = stringReference("Changelly"),
+ subtitle = stringReference("CEX"),
+ infoText = stringReference("1 POL"),
+ iconUrl = "",
+ badgeList = persistentListOf(
+ BadgeUM(
+ text = stringReference("4.9"),
+ iconRes = R.drawable.ic_star_outline_24,
+ ),
+ BadgeUM(
+ text = stringReference("5 mins"),
+ iconRes = R.drawable.ic_speed_24,
+ ),
+ BadgeUM(
+ text = stringReference("$3.45"),
+ iconRes = R.drawable.ic_gas_24,
+ ),
+ ),
+ isSelected = false,
+ labelUM = null,
+ ),
+ )
+}
+// endregion
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/provider/entity/ProviderChooseUM.kt b/core/ui/src/main/java/com/tangem/core/ui/components/provider/entity/ProviderChooseUM.kt
new file mode 100644
index 0000000000..b3a9392c87
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/provider/entity/ProviderChooseUM.kt
@@ -0,0 +1,39 @@
+package com.tangem.core.ui.components.provider.entity
+
+import androidx.compose.runtime.Immutable
+import com.tangem.core.ui.components.audits.AuditLabelUM
+import com.tangem.core.ui.components.badge.entity.BadgeUM
+import com.tangem.core.ui.extensions.TextReference
+import kotlinx.collections.immutable.ImmutableList
+
+/**
+ * Provider Row - Choose Crypto component UI Model
+ *
+ * @property title title text
+ * @property subtitle subtitle text
+ * @property infoText info text
+ * @property iconUrl icon url
+ * @property isSelected indicated whether component is selected (border outline)
+ * @property badgeList list of badge components
+ * @property labelUM label component (whether AuditLabel or text)
+ */
+data class ProviderChooseUM(
+ val title: TextReference,
+ val subtitle: TextReference,
+ val infoText: TextReference,
+ val iconUrl: String,
+ val isSelected: Boolean,
+ val badgeList: ImmutableList,
+ val labelUM: LabelUM?,
+) {
+ @Immutable
+ sealed class LabelUM {
+ data class Info(
+ val auditLabelUM: AuditLabelUM,
+ ) : LabelUM()
+
+ data class Text(
+ val text: TextReference,
+ ) : LabelUM()
+ }
+}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/extensions/ModifierExt.kt b/core/ui/src/main/java/com/tangem/core/ui/extensions/ModifierExt.kt
index a014910b24..fc74ccf197 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/extensions/ModifierExt.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/extensions/ModifierExt.kt
@@ -1,12 +1,21 @@
package com.tangem.core.ui.extensions
import androidx.compose.foundation.LocalIndication
+import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.MultipleClickPreventer
/**
@@ -38,4 +47,51 @@ fun Modifier.conditional(condition: Boolean, modifier: Modifier.() -> Modifier):
} else {
this
}
-}
\ No newline at end of file
+}
+
+/**
+ * Conditionally applies a modifier based on a boolean condition.
+ */
+@Composable
+fun Modifier.conditionalCompose(
+ condition: Boolean,
+ modifier: @Composable Modifier.() -> Modifier = { Modifier },
+ otherModifier: @Composable Modifier.() -> Modifier = { this },
+): Modifier {
+ return if (condition) {
+ then(modifier(Modifier))
+ } else {
+ otherModifier()
+ }
+}
+
+/**
+ * Border with accent outline when selected
+ */
+@Composable
+fun Modifier.selectedBorder(
+ isSelected: Boolean,
+ width: Dp = 2.5.dp,
+ color: Color = TangemTheme.colors.text.accent.copy(alpha = 0.1f),
+ radius: Dp = 16.dp,
+) = conditionalCompose(
+ condition = isSelected,
+ modifier = {
+ border(
+ width = width,
+ color = color,
+ shape = RoundedCornerShape(radius),
+ )
+ .padding(2.5.dp)
+ .border(
+ width = 1.dp,
+ color = TangemTheme.colors.text.accent,
+ shape = RoundedCornerShape(radius - 2.dp),
+ )
+ .clip(RoundedCornerShape(radius - 2.dp))
+ },
+ otherModifier = {
+ padding(2.dp)
+ .clip(RoundedCornerShape(radius - 2.dp))
+ },
+)
\ No newline at end of file
diff --git a/core/ui/src/main/res/drawable/ic_gas_24.xml b/core/ui/src/main/res/drawable/ic_gas_24.xml
new file mode 100644
index 0000000000..278945f9fa
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_gas_24.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_speed_24.xml b/core/ui/src/main/res/drawable/ic_speed_24.xml
new file mode 100644
index 0000000000..8e4390a831
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_speed_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_star_outline_24.xml b/core/ui/src/main/res/drawable/ic_star_outline_24.xml
new file mode 100644
index 0000000000..116e8fdc03
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_star_outline_24.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/paymentmethod/ui/SelectPaymentMethodBottomSheet.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/paymentmethod/ui/SelectPaymentMethodBottomSheet.kt
index 48ce4dfda8..fb80254c3c 100644
--- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/paymentmethod/ui/SelectPaymentMethodBottomSheet.kt
+++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/paymentmethod/ui/SelectPaymentMethodBottomSheet.kt
@@ -14,11 +14,11 @@ import androidx.compose.ui.draw.clip
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheet
import com.tangem.core.ui.extensions.resourceReference
+import com.tangem.core.ui.extensions.selectedBorder
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.paymentmethod.entity.PaymentMethodUM
import com.tangem.features.onramp.paymentmethod.entity.PaymentMethodsBottomSheetConfig
-import com.tangem.features.onramp.utils.selectedBorder
import kotlinx.collections.immutable.ImmutableList
@Composable
@@ -59,27 +59,16 @@ private fun SelectPaymentMethodBottomSheetContent(
val isSelected = remember(item, selectedMethodId) {
item.id == selectedMethodId
}
- val itemModifier = if (isSelected) {
- Modifier
- .fillMaxWidth()
- .selectedBorder()
- .clickable(onClick = item.onSelect)
- .padding(
- start = TangemTheme.dimens.spacing12,
- top = TangemTheme.dimens.spacing10,
- bottom = TangemTheme.dimens.spacing10,
- )
- } else {
- Modifier
- .fillMaxWidth()
- .clip(RoundedCornerShape(TangemTheme.dimens.radius16))
- .clickable(onClick = item.onSelect)
- .padding(
- start = TangemTheme.dimens.spacing12,
- top = TangemTheme.dimens.spacing10,
- bottom = TangemTheme.dimens.spacing10,
- )
- }
+ val itemModifier = Modifier
+ .fillMaxWidth()
+ .selectedBorder(isSelected = isSelected)
+ .clip(RoundedCornerShape(TangemTheme.dimens.radius16))
+ .clickable(onClick = item.onSelect)
+ .padding(
+ start = TangemTheme.dimens.spacing12,
+ top = TangemTheme.dimens.spacing10,
+ bottom = TangemTheme.dimens.spacing10,
+ )
PaymentMethodItem(
modifier = itemModifier,
paymentMethod = item,
diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/providers/ui/SelectProviderBottomSheet.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/providers/ui/SelectProviderBottomSheet.kt
index 6f74ef7c95..59cb8cb0b0 100644
--- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/providers/ui/SelectProviderBottomSheet.kt
+++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/providers/ui/SelectProviderBottomSheet.kt
@@ -26,13 +26,10 @@ import androidx.compose.ui.util.fastForEach
import coil.compose.SubcomposeAsyncImage
import coil.request.ImageRequest
import com.tangem.core.ui.components.RectangleShimmer
-import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheet
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
-import com.tangem.core.ui.extensions.TextReference
-import com.tangem.core.ui.extensions.resolveReference
-import com.tangem.core.ui.extensions.resourceReference
-import com.tangem.core.ui.extensions.stringResourceSafe
+import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheet
+import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.domain.onramp.model.OnrampPaymentMethod
@@ -41,7 +38,6 @@ import com.tangem.features.onramp.paymentmethod.ui.PaymentMethodIcon
import com.tangem.features.onramp.providers.entity.ProviderListItemUM
import com.tangem.features.onramp.providers.entity.SelectPaymentAndProviderUM
import com.tangem.features.onramp.providers.model.previewData.SelectProviderPreviewData
-import com.tangem.features.onramp.utils.selectedBorder
@Composable
internal fun SelectProviderBottomSheet(config: TangemBottomSheetConfig, content: @Composable () -> Unit) {
@@ -151,13 +147,7 @@ private fun ProviderItem(state: ProviderListItemUM, modifier: Modifier = Modifie
private fun AvailableProviderItem(state: ProviderListItemUM.Available.Content, modifier: Modifier = Modifier) {
Row(
modifier = modifier
- .then(
- if (state.isSelected) {
- Modifier.selectedBorder()
- } else {
- Modifier.clip(RoundedCornerShape(16.dp))
- },
- )
+ .selectedBorder(isSelected = state.isSelected)
.clickable(onClick = state.onClick)
.padding(all = TangemTheme.dimens.spacing12),
verticalAlignment = Alignment.CenterVertically,
@@ -227,13 +217,7 @@ private fun UnavailableProviderItem(
) {
Row(
modifier = modifier
- .then(
- if (isSelected) {
- Modifier.selectedBorder()
- } else {
- Modifier.clip(RoundedCornerShape(16.dp))
- },
- )
+ .selectedBorder(isSelected = isSelected)
.padding(all = TangemTheme.dimens.spacing12),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/utils/ModifierExt.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/utils/ModifierExt.kt
deleted file mode 100644
index 8e38b54575..0000000000
--- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/utils/ModifierExt.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.tangem.features.onramp.utils
-
-import androidx.compose.foundation.border
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.unit.dp
-import com.tangem.core.ui.res.TangemTheme
-
-@Composable
-internal fun Modifier.selectedBorder() = border(
- width = 2.5.dp,
- color = TangemTheme.colors.text.accent.copy(alpha = 0.1f),
- shape = RoundedCornerShape(18.dp),
-)
- .padding(2.5.dp)
- .border(
- width = 1.dp,
- color = TangemTheme.colors.text.accent,
- shape = RoundedCornerShape(16.dp),
- )
- .clip(RoundedCornerShape(16.dp))
\ No newline at end of file