Updated on 2026-08-14
This commit is contained in:
parent
e1ef1c4b8a
commit
03f6c241ac
12 changed files with 680 additions and 16 deletions
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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 <T : Any> InformationBlockContentScope.ListItems(
|
||||
inline fun <T : Any> InformationBlockContentScope.ListItems(
|
||||
items: ImmutableList<T>,
|
||||
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 <T : Any> InformationBlockContentScope.ListItems(
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun <T : Any> InformationBlockContentScope.GridItems(
|
||||
inline fun <T : Any> InformationBlockContentScope.GridItems(
|
||||
items: ImmutableList<T>,
|
||||
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 <T : Any> 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 <T : Any> InformationBlockContentScope.GridItems(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
inline fun <T : Any> InformationBlockContentScope.ArrowRowItems(
|
||||
items: ImmutableList<T>,
|
||||
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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
@ -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<BlockchainRowUM>(
|
||||
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
|
||||
|
|
@ -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<ChainRowUM>(
|
||||
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
|
||||
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
10
core/ui/src/main/java/com/tangem/core/ui/utils/PathUtils.kt
Normal file
10
core/ui/src/main/java/com/tangem/core/ui/utils/PathUtils.kt
Normal file
|
|
@ -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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue