From 03f6c241ac44f2937ab48764846f2f06729a5ab1 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 26 Jun 2024 14:13:06 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../block/information/InformationBlock.kt | 37 +++- .../information/InformationBlockContent.kt | 64 +++++-- .../core/ui/components/rows/ArrowRow.kt | 168 ++++++++++++++++++ .../core/ui/components/rows/BlockchainRow.kt | 99 +++++++++++ .../core/ui/components/rows/ChainRow.kt | 117 ++++++++++++ .../core/ui/components/rows/RowComponents.kt | 139 +++++++++++++++ .../components/rows/model/BlockchainRowUM.kt | 21 +++ .../ui/components/rows/model/ChainRowUM.kt | 19 ++ .../com/tangem/core/ui/res/TangemDimens.kt | 2 + .../com/tangem/core/ui/res/TangemTheme.kt | 2 +- .../com/tangem/core/ui/utils/DensityUtils.kt | 18 ++ .../com/tangem/core/ui/utils/PathUtils.kt | 10 ++ 12 files changed, 680 insertions(+), 16 deletions(-) create mode 100644 core/ui/src/main/java/com/tangem/core/ui/components/rows/ArrowRow.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/components/rows/BlockchainRow.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/components/rows/ChainRow.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/components/rows/RowComponents.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/components/rows/model/BlockchainRowUM.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/components/rows/model/ChainRowUM.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/utils/DensityUtils.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/utils/PathUtils.kt diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/block/information/InformationBlock.kt b/core/ui/src/main/java/com/tangem/core/ui/components/block/information/InformationBlock.kt index 110b0048aa..027109f071 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/block/information/InformationBlock.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/block/information/InformationBlock.kt @@ -97,6 +97,7 @@ private fun Preview_Grid() { }, content = { GridItems( + itemPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing4), items = persistentListOf( stringReference("Fist item"), stringReference("Second item"), @@ -104,6 +105,7 @@ private fun Preview_Grid() { itemContent = { PreviewItem(text = it) }, + horizontalArragement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), ) }, ) @@ -141,6 +143,7 @@ private fun Preview_List() { itemContent = { PreviewItem(it) }, + verticalArragement = Arrangement.spacedBy(TangemTheme.dimens.spacing8), ) }, ) @@ -159,7 +162,7 @@ private fun Preview_Plain() { ) { TooltipText( text = stringReference("Title"), - onInfoClick = { /* [REDACTED_TODO_COMMENT]*/ }, + onInfoClick = { }, ) Text( @@ -176,6 +179,38 @@ private fun Preview_Plain() { } } +@Composable +@Preview(showBackground = true, widthDp = 328) +@Preview(showBackground = true, widthDp = 328, uiMode = Configuration.UI_MODE_NIGHT_YES) +private fun Preview_Tree() { + TangemThemePreview { + InformationBlock( + title = { + TooltipText( + text = stringReference("Tree title"), + onInfoClick = { }, + ) + }, + content = { + ArrowRowItems( + itemPadding = PaddingValues(vertical = TangemTheme.dimens.spacing4), + items = persistentListOf( + stringReference("Fist item"), + stringReference("Second item"), + stringReference("Third item"), + ), + rootContent = { + PreviewItem(stringReference("Root")) + }, + itemContent = { + PreviewItem(it) + }, + ) + }, + ) + } +} + @Composable private fun PreviewItem(text: TextReference) { Box( diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/block/information/InformationBlockContent.kt b/core/ui/src/main/java/com/tangem/core/ui/components/block/information/InformationBlockContent.kt index 02b783e839..1a40b55863 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/block/information/InformationBlockContent.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/block/information/InformationBlockContent.kt @@ -8,26 +8,30 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.util.fastForEach +import com.tangem.core.ui.components.rows.ArrowRow import com.tangem.core.ui.res.TangemTheme import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList @Composable -fun InformationBlockContentScope.ListItems( +inline fun InformationBlockContentScope.ListItems( items: ImmutableList, itemContent: @Composable BoxScope.(T) -> Unit, modifier: Modifier = Modifier, + itemPadding: PaddingValues = PaddingValues(all = TangemTheme.dimens.spacing0), + horizontalAlignment: Alignment.Horizontal = Alignment.CenterHorizontally, + verticalArragement: Arrangement.Vertical = Arrangement.Top, ) { Column( - modifier = modifier - .padding(vertical = TangemTheme.dimens.spacing8) - .fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8, Alignment.Top), + modifier = modifier.fillMaxWidth(), + horizontalAlignment = horizontalAlignment, + verticalArrangement = verticalArragement, ) { items.fastForEach { item -> Box( - modifier = Modifier.fillMaxWidth(), + modifier = Modifier + .padding(itemPadding) + .fillMaxWidth(), ) { itemContent(item) } @@ -36,10 +40,13 @@ fun InformationBlockContentScope.ListItems( } @Composable -fun InformationBlockContentScope.GridItems( +inline fun InformationBlockContentScope.GridItems( items: ImmutableList, itemContent: @Composable BoxScope.(T) -> Unit, modifier: Modifier = Modifier, + itemPadding: PaddingValues = PaddingValues(all = TangemTheme.dimens.spacing0), + verticalAlignment: Alignment.Vertical = Alignment.Top, + horizontalArragement: Arrangement.Horizontal = Arrangement.Start, ) { val rowItems by remember(items) { derivedStateOf { @@ -57,15 +64,15 @@ fun InformationBlockContentScope.GridItems( ) { rowItems.fastForEach { row -> Row( - modifier = Modifier - .padding(vertical = TangemTheme.dimens.spacing8) - .fillMaxWidth(), - verticalAlignment = Alignment.Top, - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12, Alignment.Start), + modifier = Modifier.fillMaxWidth(), + verticalAlignment = verticalAlignment, + horizontalArrangement = horizontalArragement, ) { row.fastForEach { item -> Box( - modifier = Modifier.weight(1f), + modifier = Modifier + .padding(itemPadding) + .weight(1f), contentAlignment = Alignment.Center, ) { itemContent(item) @@ -74,4 +81,33 @@ fun InformationBlockContentScope.GridItems( } } } +} + +@Composable +inline fun InformationBlockContentScope.ArrowRowItems( + items: ImmutableList, + rootContent: @Composable BoxScope.() -> Unit, + itemContent: @Composable BoxScope.(T) -> Unit, + modifier: Modifier = Modifier, + itemPadding: PaddingValues = PaddingValues(all = TangemTheme.dimens.spacing0), +) { + Column( + modifier = modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Box( + modifier = Modifier.fillMaxWidth(), + contentAlignment = Alignment.CenterStart, + content = rootContent, + ) + + items.forEachIndexed { index, item -> + ArrowRow( + modifier = Modifier.fillMaxWidth(), + content = { itemContent(item) }, + contentPadding = itemPadding, + isLastItem = index == items.size - 1, + ) + } + } } \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/rows/ArrowRow.kt b/core/ui/src/main/java/com/tangem/core/ui/components/rows/ArrowRow.kt new file mode 100644 index 0000000000..0e594fbd91 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/rows/ArrowRow.kt @@ -0,0 +1,168 @@ +package com.tangem.core.ui.components.rows + +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.layout.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Rect +import androidx.compose.ui.graphics.* +import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.graphics.drawscope.drawIntoCanvas +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.* +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.utils.* + +@Composable +inline fun ArrowRow( + isLastItem: Boolean, + content: @Composable() (BoxScope.() -> Unit), + modifier: Modifier = Modifier, + contentPadding: PaddingValues = PaddingValues(all = TangemTheme.dimens.spacing0), +) { + val density = LocalDensity.current.density + val defaultRowHeight = TangemTheme.dimens.size0 + var itemHeight by remember { mutableStateOf(defaultRowHeight) } + + Row( + modifier = modifier.onSizeChanged { size -> + val height = size.height.toFloat() + if (height != itemHeight.toPx(density)) { + itemHeight = convertPxToDp(px = height, density = density) + } + }, + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Start, + ) { + ChildArrow( + childHeight = itemHeight, + isLastChild = isLastItem, + ) + + Box( + modifier = Modifier + .padding(contentPadding) + .fillMaxWidth(), + contentAlignment = Alignment.CenterStart, + ) { + content() + } + } +} + +@Suppress("LongParameterList") +@Immutable +private class ChildArrowScope( + val figureRect: Rect, + val arrowHeadRect: Rect, + val curvedArrowRect: Rect, + val arrowStrokeWidth: Float, + val arrowHeadRadius: Float, + val strokeColor: Color, + drawScope: DrawScope, +) : DrawScope by drawScope + +@Composable +fun ChildArrow(childHeight: Dp, isLastChild: Boolean) { + val figureWidth = TangemTheme.dimens.size40 + + val strokeColor = TangemTheme.colors.stroke.secondary + val arrowStrokeWidthDp = TangemTheme.dimens.size1 + + val arrowHeadRadiusDp = TangemTheme.dimens.size1 + + val figureRectDp = DpRect( + origin = DpOffset.Zero, + size = DpSize(width = TangemTheme.dimens.size40, height = childHeight), + ) + + val arrowHeadSize = DpSize( + width = TangemTheme.dimens.size6, + height = TangemTheme.dimens.size6, + ) + val arrowHeadRectDp = DpRect( + origin = DpOffset( + x = figureWidth - arrowHeadSize.width, + y = figureRectDp.size.center.y - arrowHeadSize.center.y, + ), + size = arrowHeadSize, + ) + + val curvedArrowRectDp = DpRect( + top = figureRectDp.top, + left = TangemTheme.dimens.size18, + right = figureRectDp.right - arrowHeadRectDp.width, + bottom = figureRectDp.size.center.y, + ) + + Canvas( + modifier = Modifier + .width(figureWidth) + .height(childHeight), + ) { + val scope = ChildArrowScope( + figureRect = figureRectDp.toRect(), + arrowHeadRect = arrowHeadRectDp.toRect(), + curvedArrowRect = curvedArrowRectDp.toRect(), + arrowStrokeWidth = arrowStrokeWidthDp.toPx(), + arrowHeadRadius = arrowHeadRadiusDp.toPx(), + strokeColor = strokeColor, + drawScope = this, + ) + + scope.drawCurveArrow() + scope.drawArrowHead() + + if (!isLastChild) { + scope.drawArrowLine() + } + } +} + +private fun ChildArrowScope.drawArrowHead() { + val arrowHeadPath = Path().apply { + moveTo(arrowHeadRect.centerRight) + lineTo(arrowHeadRect.topLeft) + lineTo(arrowHeadRect.bottomLeft) + close() + } + val paint = Paint().apply { + color = strokeColor + style = PaintingStyle.Fill + pathEffect = PathEffect.cornerPathEffect(arrowHeadRadius) + } + drawIntoCanvas { canvas -> + canvas.drawOutline( + outline = Outline.Generic(arrowHeadPath), + paint = paint, + ) + } +} + +private fun ChildArrowScope.drawCurveArrow() { + val curveArrowPath = Path().apply { + moveTo(curvedArrowRect.topLeft) + quadraticBezierTo( + control = curvedArrowRect.bottomLeft, + end = curvedArrowRect.bottomRight, + ) + } + drawPath( + path = curveArrowPath, + color = strokeColor, + style = Stroke(width = arrowStrokeWidth), + ) +} + +private fun ChildArrowScope.drawArrowLine() { + drawLine( + color = strokeColor, + start = curvedArrowRect.topLeft, + end = Offset(curvedArrowRect.left, figureRect.bottom), + strokeWidth = arrowStrokeWidth, + ) +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/rows/BlockchainRow.kt b/core/ui/src/main/java/com/tangem/core/ui/components/rows/BlockchainRow.kt new file mode 100644 index 0000000000..8d6e4165e3 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/rows/BlockchainRow.kt @@ -0,0 +1,99 @@ +package com.tangem.core.ui.components.rows + +import android.content.res.Configuration +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider +import com.tangem.core.ui.R +import com.tangem.core.ui.components.TangemSwitch +import com.tangem.core.ui.components.rows.model.BlockchainRowUM +import com.tangem.core.ui.extensions.stringReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview + +/** + * [Figma Component](https://www.figma.com/design/14ISV23YB1yVW1uNVwqrKv/Android?node-id=2737-2800&t=ewlXfWwbDnRhjw4B-4) + * */ +@Composable +fun BlockchainRow(model: BlockchainRowUM, action: @Composable BoxScope.() -> Unit, modifier: Modifier = Modifier) { + RowContentContainer( + modifier = modifier + .heightIn(min = TangemTheme.dimens.size52) + .padding( + vertical = TangemTheme.dimens.spacing16, + horizontal = TangemTheme.dimens.spacing8, + ), + icon = { + RowIcon( + modifier = Modifier.size(TangemTheme.dimens.size22), + resId = model.icon.resId, + isColored = model.icon.isColored, + showAccentBadge = model.isAccented, + ) + }, + text = { + RowTitleAndSubtitle( + title = model.name, + subtitle = model.type, + accentTitle = model.usePrimaryTextColor, + accentSubtitle = model.isAccented, + ) + }, + action = action, + ) +} + +// region Preview +@Preview(showBackground = true, widthDp = 360) +@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun Preview_BlockchainRow(@PreviewParameter(BlockchainRowParameterProvider::class) state: BlockchainRowUM) { + TangemThemePreview { + ArrowRow( + modifier = Modifier.background(TangemTheme.colors.background.primary), + isLastItem = false, + content = { + BlockchainRow( + model = state, + action = { + TangemSwitch(onCheckedChange = { /* [REDACTED_TODO_COMMENT]*/ }, checked = true) + }, + ) + }, + ) + } +} + +private class BlockchainRowParameterProvider : CollectionPreviewParameterProvider( + collection = listOf( + BlockchainRowUM( + name = stringReference("BNB BEACON CHAIN"), + type = stringReference("BEP20"), + icon = BlockchainRowUM.Icon(R.drawable.ic_bsc_16, isColored = false), + isAccented = true, + usePrimaryTextColor = false, + ), + BlockchainRowUM( + name = stringReference("1234567890111213141516171819"), + type = stringReference("BEP20"), + icon = BlockchainRowUM.Icon(R.drawable.ic_bsc_16, isColored = false), + isAccented = false, + usePrimaryTextColor = true, + ), + BlockchainRowUM( + name = stringReference("BNB BEACON CHAIN"), + type = stringReference("1234567890111213141516171819"), + icon = BlockchainRowUM.Icon(R.drawable.img_bsc_22, isColored = true), + isAccented = false, + usePrimaryTextColor = false, + ), + ), +) +// endregion Preview \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/rows/ChainRow.kt b/core/ui/src/main/java/com/tangem/core/ui/components/rows/ChainRow.kt new file mode 100644 index 0000000000..24645b9c17 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/rows/ChainRow.kt @@ -0,0 +1,117 @@ +package com.tangem.core.ui.components.rows + +import android.content.res.Configuration +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider +import com.tangem.core.ui.R +import com.tangem.core.ui.components.rows.model.ChainRowUM +import com.tangem.core.ui.extensions.stringReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview + +/** + * [Figma Component](https://www.figma.com/design/14ISV23YB1yVW1uNVwqrKv/Android?node-id=1608-1147&t=ewlXfWwbDnRhjw4B-4) + * */ +@Composable +fun ChainRow(model: ChainRowUM, modifier: Modifier = Modifier, action: @Composable BoxScope.() -> Unit = {}) { + RowContentContainer( + modifier = modifier + .heightIn(min = TangemTheme.dimens.size68) + .padding( + vertical = TangemTheme.dimens.spacing12, + horizontal = TangemTheme.dimens.spacing14, + ), + icon = { + RowIcon( + modifier = Modifier.size(TangemTheme.dimens.size36), + resId = model.icon.resId, + isColored = model.icon.isColored, + showAccentBadge = false, + ) + }, + text = { + RowTitleAndSubtitle( + title = model.name, + subtitle = model.type, + accentTitle = true, + accentSubtitle = false, + ) + }, + action = action, + ) +} + +// region Preview +@Preview(showBackground = true, widthDp = 360) +@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun Preview_ChainRow(@PreviewParameter(ChainRowParameterProvider::class) state: ChainRowUM) { + TangemThemePreview { + ChainRow( + modifier = Modifier.background(TangemTheme.colors.background.primary), + model = state, + action = { + IconButton( + modifier = Modifier.size(TangemTheme.dimens.size32), + onClick = { /* [REDACTED_TODO_COMMENT]*/ }, + ) { + Icon( + modifier = Modifier.size(TangemTheme.dimens.size24), + tint = TangemTheme.colors.icon.informative, + painter = painterResource(id = R.drawable.ic_chevron_24), + contentDescription = null, + ) + } + }, + ) + } +} + +private class ChainRowParameterProvider : CollectionPreviewParameterProvider( + collection = listOf( + ChainRowUM( + name = stringReference("Cardano"), + type = stringReference("ADA"), + icon = ChainRowUM.Icon( + resId = R.drawable.img_cardano_22, + isColored = true, + ), + ), + ChainRowUM( + name = stringReference("Binance"), + type = stringReference("BNB"), + icon = ChainRowUM.Icon( + resId = R.drawable.ic_bsc_16, + isColored = false, + ), + ), + ChainRowUM( + name = stringReference("123456789010111213141516"), + type = stringReference("BNB"), + icon = ChainRowUM.Icon( + resId = R.drawable.ic_bsc_16, + isColored = false, + ), + ), + ChainRowUM( + name = stringReference("123456789010111213141516"), + type = stringReference("123456789010111213141516"), + icon = ChainRowUM.Icon( + resId = R.drawable.ic_bsc_16, + isColored = false, + ), + ), + ), +) +// endregion Preview \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/rows/RowComponents.kt b/core/ui/src/main/java/com/tangem/core/ui/components/rows/RowComponents.kt new file mode 100644 index 0000000000..e0ac20cdc2 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/rows/RowComponents.kt @@ -0,0 +1,139 @@ +package com.tangem.core.ui.components.rows + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.CircleShape +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.res.painterResource +import androidx.compose.ui.text.style.TextOverflow +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme + +@Composable +internal inline fun RowContentContainer( + icon: @Composable BoxScope.() -> Unit, + text: @Composable BoxScope.() -> Unit, + action: @Composable BoxScope.() -> Unit, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8, Alignment.Start), + ) { + Box( + contentAlignment = Alignment.Center, + content = icon, + ) + Box( + modifier = Modifier + .weight(1f) + .heightIn(min = TangemTheme.dimens.size22), + contentAlignment = Alignment.CenterStart, + content = text, + ) + Box( + modifier = Modifier + .requiredWidthIn(max = TangemTheme.dimens.size48) + .heightIn(min = TangemTheme.dimens.size24), + contentAlignment = Alignment.CenterEnd, + content = action, + ) + } +} + +@Composable +internal fun RowTitleAndSubtitle( + title: TextReference, + subtitle: TextReference, + accentTitle: Boolean, + accentSubtitle: Boolean, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier, + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4), + ) { + Text( + modifier = Modifier.weight(weight = 10f, fill = false), + text = title.resolveReference(), + style = TangemTheme.typography.subtitle2, + color = if (accentTitle) TangemTheme.colors.text.primary1 else TangemTheme.colors.text.secondary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + + Text( + modifier = Modifier.weight(weight = 4f, fill = false), + text = subtitle.resolveReference(), + style = TangemTheme.typography.body2, + color = if (accentSubtitle) TangemTheme.colors.text.accent else TangemTheme.colors.text.secondary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } +} + +@Composable +internal fun RowIcon( + @DrawableRes resId: Int, + isColored: Boolean, + showAccentBadge: Boolean, + modifier: Modifier = Modifier, +) { + Box(modifier = modifier) { + if (isColored) { + Image( + modifier = Modifier.matchParentSize(), + painter = painterResource(id = resId), + contentDescription = null, + ) + } else { + Icon( + modifier = Modifier + .background( + color = TangemTheme.colors.button.secondary, + shape = CircleShape, + ) + .matchParentSize(), + painter = painterResource(id = resId), + tint = TangemTheme.colors.icon.informative, + contentDescription = null, + ) + } + + if (showAccentBadge) { + Badge(modifier = Modifier.align(Alignment.TopEnd)) + } + } +} + +@Composable +private fun Badge(modifier: Modifier = Modifier) { + Box( + modifier = modifier + .size(TangemTheme.dimens.size6) + .background( + color = TangemTheme.colors.background.primary, + shape = CircleShape, + ), + ) { + Box( + modifier = Modifier + .padding(all = TangemTheme.dimens.spacing1) + .matchParentSize() + .background( + color = TangemTheme.colors.icon.accent, + shape = CircleShape, + ), + ) + } +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/rows/model/BlockchainRowUM.kt b/core/ui/src/main/java/com/tangem/core/ui/components/rows/model/BlockchainRowUM.kt new file mode 100644 index 0000000000..dbb8ae529d --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/rows/model/BlockchainRowUM.kt @@ -0,0 +1,21 @@ +package com.tangem.core.ui.components.rows.model + +import androidx.annotation.DrawableRes +import androidx.compose.runtime.Immutable +import com.tangem.core.ui.extensions.TextReference + +@Immutable +data class BlockchainRowUM( + val name: TextReference, + val type: TextReference, + val icon: Icon, + val isAccented: Boolean, + val usePrimaryTextColor: Boolean, +) { + + @Immutable + data class Icon( + @DrawableRes val resId: Int, + val isColored: Boolean, + ) +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/rows/model/ChainRowUM.kt b/core/ui/src/main/java/com/tangem/core/ui/components/rows/model/ChainRowUM.kt new file mode 100644 index 0000000000..58e337a805 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/rows/model/ChainRowUM.kt @@ -0,0 +1,19 @@ +package com.tangem.core.ui.components.rows.model + +import androidx.annotation.DrawableRes +import androidx.compose.runtime.Immutable +import com.tangem.core.ui.extensions.TextReference + +@Immutable +data class ChainRowUM( + val name: TextReference, + val type: TextReference, + val icon: Icon, +) { + + @Immutable + data class Icon( + @DrawableRes val resId: Int, + val isColored: Boolean, + ) +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt index 2ad32a8f6f..4d47c4bf0f 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt @@ -45,6 +45,7 @@ data class TangemDimens internal constructor( val size2: Dp = 2.dp, val size4: Dp = 4.dp, val size5: Dp = 5.dp, + val size6: Dp = 6.dp, val size7: Dp = 7.dp, val size8: Dp = 8.dp, val size9: Dp = 9.dp, @@ -56,6 +57,7 @@ data class TangemDimens internal constructor( val size16: Dp = 16.dp, val size18: Dp = 18.dp, val size20: Dp = 20.dp, + val size22: Dp = 22.dp, val size24: Dp = 24.dp, val size28: Dp = 28.dp, val size30: Dp = 30.dp, diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt index 58552b1353..ea874c3bfb 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt @@ -139,7 +139,7 @@ private fun lightThemeColors(): TangemColors { ), stroke = TangemColors.Stroke( primary = TangemColorPalette.Light2, - secondary = TangemColorPalette.Dark5, + secondary = TangemColorPalette.Light5, transparency = TangemColorPalette.White, ), field = TangemColors.Field( diff --git a/core/ui/src/main/java/com/tangem/core/ui/utils/DensityUtils.kt b/core/ui/src/main/java/com/tangem/core/ui/utils/DensityUtils.kt new file mode 100644 index 0000000000..105d2416d3 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/utils/DensityUtils.kt @@ -0,0 +1,18 @@ +package com.tangem.core.ui.utils + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Dp + +@Stable +@Composable +fun Dp.toPx(): Float = toPx(density = LocalDensity.current.density) + +@Stable +@Composable +fun convertPxToDp(px: Float): Dp = convertPxToDp(px, density = LocalDensity.current.density) + +fun Dp.toPx(density: Float): Float = this.value * density + +fun convertPxToDp(px: Float, density: Float): Dp = Dp(value = px / density) \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/utils/PathUtils.kt b/core/ui/src/main/java/com/tangem/core/ui/utils/PathUtils.kt new file mode 100644 index 0000000000..8ab1fe470b --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/utils/PathUtils.kt @@ -0,0 +1,10 @@ +package com.tangem.core.ui.utils + +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Path + +fun Path.lineTo(offset: Offset) = lineTo(offset.x, offset.y) + +fun Path.moveTo(offset: Offset) = moveTo(offset.x, offset.y) + +fun Path.quadraticBezierTo(control: Offset, end: Offset) = quadraticBezierTo(control.x, control.y, end.x, end.y) \ No newline at end of file