Updated on 2026-08-14

This commit is contained in:
Tangem 2026-03-04 16:05:34 +05:00
parent 1858d5453a
commit 1ffec50319
17 changed files with 305 additions and 98 deletions

View file

@ -1,22 +1,18 @@
package com.tangem.core.ui.ds.row.header
import android.content.res.Configuration
import androidx.annotation.DrawableRes
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
@ -25,10 +21,13 @@ import com.tangem.core.ui.components.SpacerWMax
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.ds.image.TangemIcon
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.ds.row.internal.TangemRowTail
import com.tangem.core.ui.ds.row.internal.TangemRowTailUM
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.test.TokenElementsTestTags
import org.burnoutcrew.reorderable.ReorderableLazyListState
/**
* UI model for header row component
@ -37,13 +36,19 @@ import com.tangem.core.ui.test.TokenElementsTestTags
* @param modifier Modifier for the composable
*/
@Composable
fun TangemHeaderRow(headerRowUM: TangemHeaderRowUM, modifier: Modifier = Modifier, isBalanceHidden: Boolean = false) {
fun TangemHeaderRow(
headerRowUM: TangemHeaderRowUM,
modifier: Modifier = Modifier,
reorderableState: ReorderableLazyListState? = null,
isBalanceHidden: Boolean = false,
) {
TangemHeaderRow(
headTangemIconUM = headerRowUM.startIconUM,
footerTangemIconRes = headerRowUM.endIconRes,
tailUM = headerRowUM.tailUM,
title = headerRowUM.title,
subtitle = headerRowUM.subtitle,
isBalanceHidden = isBalanceHidden,
reorderableState = reorderableState,
modifier = modifier,
)
}
@ -54,7 +59,7 @@ fun TangemHeaderRow(headerRowUM: TangemHeaderRowUM, modifier: Modifier = Modifie
* @param modifier Modifier for the composable
* @param subtitle Optional subtitle as a TextReference
* @param onItemClick Optional click callback for the row
* @param footerTangemIconRes Optional drawable resource ID for the footer icon
* @param tailUM Optional TailUM for the tail content
* @param titleContent Composable lambda for the title content
* @param headContent Composable lambda for the head content
*/
@ -64,7 +69,7 @@ fun TangemHeaderRow(
isBalanceHidden: Boolean = false,
subtitle: TextReference? = null,
onItemClick: (() -> Unit)? = null,
@DrawableRes footerTangemIconRes: Int? = null,
tailUM: TangemRowTailUM = TangemRowTailUM.Empty,
titleContent: @Composable (Modifier) -> Unit,
headContent: @Composable (Modifier) -> Unit,
) {
@ -101,17 +106,7 @@ fun TangemHeaderRow(
)
}
SpacerWMax()
AnimatedVisibility(
visible = footerTangemIconRes != null,
) {
val wrappedIconUM = remember(this) { requireNotNull(footerTangemIconRes) }
Icon(
imageVector = ImageVector.vectorResource(id = wrappedIconUM),
contentDescription = null,
tint = TangemTheme.colors2.graphic.neutral.secondary,
modifier = Modifier.size(TangemTheme.dimens2.x4),
)
}
TangemRowTail(tangemRowTailUM = tailUM)
}
}
@ -133,7 +128,8 @@ fun TangemHeaderRow(
isBalanceHidden: Boolean = false,
subtitle: TextReference? = null,
headTangemIconUM: TangemIconUM? = null,
@DrawableRes footerTangemIconRes: Int? = null,
tailUM: TangemRowTailUM = TangemRowTailUM.Empty,
reorderableState: ReorderableLazyListState? = null,
isEnabled: Boolean = false,
onItemClick: (() -> Unit)? = null,
) {
@ -182,17 +178,10 @@ fun TangemHeaderRow(
)
}
SpacerWMax()
AnimatedVisibility(
visible = footerTangemIconRes != null,
) {
val wrappedIconUM = remember(this) { requireNotNull(footerTangemIconRes) }
Icon(
imageVector = ImageVector.vectorResource(id = wrappedIconUM),
contentDescription = null,
tint = TangemTheme.colors2.graphic.neutral.secondary,
modifier = Modifier.size(TangemTheme.dimens2.x4),
)
}
TangemRowTail(
tangemRowTailUM = tailUM,
reorderableState = reorderableState,
)
}
}
@ -217,7 +206,25 @@ private class PreviewProvider : PreviewParameterProvider<TangemHeaderRowUM> {
startIconUM = TangemIconUM.Currency(
currencyIconState = CurrencyIconState.Locked,
),
endIconRes = R.drawable.ic_minimize_24,
tailUM = TangemRowTailUM.Empty,
title = stringReference("Account"),
subtitle = stringReference("\$ 42,900.17"),
),
TangemHeaderRowUM(
id = "1",
startIconUM = TangemIconUM.Currency(
currencyIconState = CurrencyIconState.Locked,
),
tailUM = TangemRowTailUM.Icon(R.drawable.ic_arrow_collapse_24),
title = stringReference("Account"),
subtitle = stringReference("\$ 42,900.17"),
),
TangemHeaderRowUM(
id = "1",
startIconUM = TangemIconUM.Currency(
currencyIconState = CurrencyIconState.Locked,
),
tailUM = TangemRowTailUM.Icon(R.drawable.ic_group_drop_24),
title = stringReference("Account"),
subtitle = stringReference("\$ 42,900.17"),
),

View file

@ -1,9 +1,9 @@
package com.tangem.core.ui.ds.row.header
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.ds.row.TangemRowUM
import com.tangem.core.ui.ds.row.internal.TangemRowTailUM
import com.tangem.core.ui.extensions.TextReference
/**
@ -13,7 +13,7 @@ import com.tangem.core.ui.extensions.TextReference
* @param title Title text reference
* @param subtitle Subtitle text reference (optional)
* @param startIconUM Icon UI model (optional)
* @param endIconRes Icon UI model (optional)
* @param tailUM Tail UI model (optional)
* @param isEnabled Flag indicating if click is enabled
* @param onItemClick Callback for item click (optional)
*/
@ -23,7 +23,7 @@ data class TangemHeaderRowUM(
val title: TextReference,
val subtitle: TextReference? = null,
val startIconUM: TangemIconUM? = null,
@DrawableRes val endIconRes: Int? = null,
val tailUM: TangemRowTailUM = TangemRowTailUM.Empty,
val isEnabled: Boolean = false,
val onItemClick: (() -> Unit)? = null,
) : TangemRowUM

View file

@ -1,7 +1,9 @@
package com.tangem.core.ui.ds.row.token.internal
package com.tangem.core.ui.ds.row.internal
import androidx.annotation.DrawableRes
import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
@ -9,11 +11,10 @@ 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.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextOverflow
import com.tangem.core.ui.R
import com.tangem.core.ui.ds.row.token.TangemTokenRowUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveAnnotatedReference
import com.tangem.core.ui.res.TangemTheme
@ -22,37 +23,48 @@ import org.burnoutcrew.reorderable.ReorderableLazyListState
import org.burnoutcrew.reorderable.detectReorder
@Composable
internal fun TokenRowTail(
tailUM: TangemTokenRowUM.TailUM,
reorderableTokenListState: ReorderableLazyListState?,
internal fun TangemRowTail(
tangemRowTailUM: TangemRowTailUM,
modifier: Modifier = Modifier,
reorderableState: ReorderableLazyListState? = null,
) {
AnimatedContent(
targetState = tailUM,
targetState = tangemRowTailUM,
label = "Update non content fiat block",
modifier = modifier,
modifier = modifier.height(TangemTheme.dimens2.x4),
contentKey = { it::class.java },
) { animatedState ->
val innerModifier = Modifier.padding(start = TangemTheme.dimens2.x2)
when (animatedState) {
TangemTokenRowUM.TailUM.Empty -> Unit
is TangemTokenRowUM.TailUM.Draggable -> DraggableImage(
reorderableTokenListState = reorderableTokenListState,
TangemRowTailUM.Empty -> Unit
is TangemRowTailUM.Draggable -> DraggableImage(
iconRes = animatedState.iconRes,
reorderableState = reorderableState,
modifier = innerModifier,
)
is TangemTokenRowUM.TailUM.Text -> ContentText(text = animatedState.text, modifier = innerModifier)
is TangemRowTailUM.Text -> ContentText(text = animatedState.text, modifier = innerModifier)
is TangemRowTailUM.Icon -> Icon(
imageVector = ImageVector.vectorResource(animatedState.iconRes),
contentDescription = null,
modifier = modifier,
tint = TangemTheme.colors2.graphic.neutral.tertiaryConstant,
)
}
}
}
@Composable
private fun DraggableImage(reorderableTokenListState: ReorderableLazyListState?, modifier: Modifier = Modifier) {
private fun DraggableImage(
@DrawableRes iconRes: Int,
reorderableState: ReorderableLazyListState?,
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier
.size(size = TangemTheme.dimens2.x6)
.then(
other = if (reorderableTokenListState != null) {
Modifier.detectReorder(reorderableTokenListState)
other = if (reorderableState != null) {
Modifier.detectReorder(reorderableState)
} else {
Modifier
},
@ -61,7 +73,7 @@ private fun DraggableImage(reorderableTokenListState: ReorderableLazyListState?,
contentAlignment = Alignment.Center,
) {
Icon(
painter = painterResource(id = R.drawable.ic_drag_24),
imageVector = ImageVector.vectorResource(iconRes),
tint = TangemTheme.colors2.graphic.neutral.tertiaryConstant,
contentDescription = null,
)

View file

@ -0,0 +1,25 @@
package com.tangem.core.ui.ds.row.internal
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.extensions.TextReference
/**
* Tail UI model for row components
*/
@Immutable
sealed class TangemRowTailUM {
data class Text(
val text: TextReference,
) : TangemRowTailUM()
data class Icon(
@DrawableRes val iconRes: Int,
) : TangemRowTailUM()
data class Draggable(
@DrawableRes val iconRes: Int,
) : TangemRowTailUM()
data object Empty : TangemRowTailUM()
}

View file

@ -19,6 +19,7 @@ import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameter
import com.tangem.core.ui.ds.image.TangemIcon
import com.tangem.core.ui.ds.row.TangemRowContainer
import com.tangem.core.ui.ds.row.TangemRowLayoutId
import com.tangem.core.ui.ds.row.internal.TangemRowTail
import com.tangem.core.ui.ds.row.token.internal.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
@ -30,16 +31,16 @@ import org.burnoutcrew.reorderable.ReorderableLazyListState
*
* [Token Row](https://www.figma.com/design/RU7AIgwHtGdMfy83T5UOoR/Core-Library?node-id=8207-17583&t=k8dyaykorsNocGVq-4)
*
* @param tokenRowUM The user model containing the data for the token row.
* @param isBalanceHidden A boolean indicating whether the balance should be hidden.
* @param reorderableTokenListState The state of the reorderable lazy list, if applicable.
* @param modifier The modifier to be applied to the row.
* @param tokenRowUM The user model containing the data for the token row.
* @param isBalanceHidden A boolean indicating whether the balance should be hidden.
* @param reorderableState The state of the reorderable lazy list, if applicable.
* @param modifier The modifier to be applied to the row.
*/
@Composable
fun TangemTokenRow(
tokenRowUM: TangemTokenRowUM,
isBalanceHidden: Boolean,
reorderableTokenListState: ReorderableLazyListState?,
reorderableState: ReorderableLazyListState?,
modifier: Modifier = Modifier,
) {
TangemRowContainer(
@ -88,9 +89,9 @@ fun TangemTokenRow(
.testTag(tag = TokenElementsTestTags.TOKEN_CRYPTO_AMOUNT),
)
TokenRowTail(
tailUM = tokenRowUM.tailUM,
reorderableTokenListState = reorderableTokenListState,
TangemRowTail(
tangemRowTailUM = tokenRowUM.tailUM,
reorderableState = reorderableState,
modifier = Modifier
.layoutId(layoutId = TangemRowLayoutId.TAIL)
.testTag(tag = TokenElementsTestTags.TOKEN_NON_FIAT_BLOCK),
@ -114,18 +115,18 @@ fun TangemTokenRow(
*
* [Token Row](https://www.figma.com/design/RU7AIgwHtGdMfy83T5UOoR/Core-Library?node-id=8207-17583&t=k8dyaykorsNocGVq-4)
*
* @param tokenRowUM The user model containing the data for the token row.
* @param headComponent The composable function representing the head component.
* @param titleComponent The composable function representing the title component.
* @param isBalanceHidden A boolean indicating whether the balance should be hidden.
* @param reorderableTokenListState The state of the reorderable lazy list, if applicable.
* @param modifier The modifier to be applied to the row.
* @param tokenRowUM The user model containing the data for the token row.
* @param headComponent The composable function representing the head component.
* @param titleComponent The composable function representing the title component.
* @param isBalanceHidden A boolean indicating whether the balance should be hidden.
* @param reorderableState The state of the reorderable lazy list, if applicable.
* @param modifier The modifier to be applied to the row.
*/
@Composable
fun TangemTokenRow(
tokenRowUM: TangemTokenRowUM,
isBalanceHidden: Boolean,
reorderableTokenListState: ReorderableLazyListState?,
reorderableState: ReorderableLazyListState?,
modifier: Modifier = Modifier,
headComponent: @Composable (Modifier) -> Unit,
titleComponent: @Composable (Modifier) -> Unit,
@ -183,9 +184,9 @@ fun TangemTokenRow(
.testTag(tag = TokenElementsTestTags.TOKEN_CRYPTO_AMOUNT),
)
TokenRowTail(
tailUM = tokenRowUM.tailUM,
reorderableTokenListState = reorderableTokenListState,
TangemRowTail(
tangemRowTailUM = tokenRowUM.tailUM,
reorderableState = reorderableState,
modifier = Modifier
.layoutId(layoutId = TangemRowLayoutId.TAIL)
.testTag(tag = TokenElementsTestTags.TOKEN_NON_FIAT_BLOCK),
@ -232,7 +233,7 @@ private fun TangemTokenRow_Preview(
TangemTokenRow(
tokenRowUM = tokenRowUM,
isBalanceHidden = false,
reorderableTokenListState = null,
reorderableState = null,
modifier = Modifier.background(TangemTheme.colors2.surface.level1),
)
}

View file

@ -6,6 +6,7 @@ import com.tangem.core.ui.components.marketprice.PriceChangeState
import com.tangem.core.ui.ds.badge.TangemBadgeUM
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.ds.row.TangemRowUM
import com.tangem.core.ui.ds.row.internal.TangemRowTailUM
import com.tangem.core.ui.extensions.TextReference
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@ -32,7 +33,7 @@ sealed class TangemTokenRowUM : TangemRowUM {
abstract val bottomEndContentUM: EndContentUM
/** Token row tail UM */
abstract val tailUM: TailUM
abstract val tailUM: TangemRowTailUM
/** Promo banner UM */
abstract val promoBannerUM: PromoBannerUM
@ -54,7 +55,7 @@ sealed class TangemTokenRowUM : TangemRowUM {
override val topEndContentUM: EndContentUM,
override val bottomEndContentUM: EndContentUM,
override val promoBannerUM: PromoBannerUM = PromoBannerUM.Empty,
override val tailUM: TailUM = TailUM.Empty,
override val tailUM: TangemRowTailUM = TangemRowTailUM.Empty,
override val onItemClick: (() -> Unit)?,
override val onItemLongClick: (() -> Unit)?,
) : TangemTokenRowUM()
@ -71,7 +72,7 @@ sealed class TangemTokenRowUM : TangemRowUM {
override val topEndContentUM: EndContentUM = EndContentUM.Loading
override val bottomEndContentUM: EndContentUM = EndContentUM.Loading
override val promoBannerUM: PromoBannerUM = PromoBannerUM.Empty
override val tailUM: TailUM = TailUM.Empty
override val tailUM: TangemRowTailUM = TangemRowTailUM.Empty
override val onItemClick: (() -> Unit)? = null
override val onItemLongClick: (() -> Unit)? = null
}
@ -84,7 +85,7 @@ sealed class TangemTokenRowUM : TangemRowUM {
override val headIconUM: TangemIconUM.Currency,
override val titleUM: TitleUM,
override val subtitleUM: SubtitleUM,
override val tailUM: TailUM,
override val tailUM: TangemRowTailUM,
override val onItemClick: (() -> Unit)?,
override val onItemLongClick: (() -> Unit)?,
override val topEndContentUM: EndContentUM = EndContentUM.Empty,
@ -154,15 +155,4 @@ sealed class TangemTokenRowUM : TangemRowUM {
data object Empty : PromoBannerUM()
}
@Immutable
sealed class TailUM {
data class Text(
val text: TextReference,
) : TailUM()
data object Draggable : TailUM()
data object Empty : TailUM()
}
}

View file

@ -7,6 +7,7 @@ import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.components.marketprice.PriceChangeState
import com.tangem.core.ui.components.marketprice.PriceChangeType
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.ds.row.internal.TangemRowTailUM
import com.tangem.core.ui.ds.row.token.TangemTokenRowUM
import com.tangem.core.ui.extensions.combinedReference
import com.tangem.core.ui.extensions.stringReference
@ -123,7 +124,7 @@ internal object TangemTokenRowPreviewData {
topEndContentUM = topEndContentUM,
bottomEndContentUM = bottomEndContentUM,
promoBannerUM = TangemTokenRowUM.PromoBannerUM.Empty,
tailUM = TangemTokenRowUM.TailUM.Empty,
tailUM = TangemRowTailUM.Empty,
onItemClick = {},
onItemLongClick = {},
)
@ -150,7 +151,7 @@ internal object TangemTokenRowPreviewData {
),
bottomEndContentUM = bottomEndContentUM,
promoBannerUM = TangemTokenRowUM.PromoBannerUM.Empty,
tailUM = TangemTokenRowUM.TailUM.Empty,
tailUM = TangemRowTailUM.Empty,
onItemClick = {},
onItemLongClick = {},
)
@ -164,7 +165,7 @@ internal object TangemTokenRowPreviewData {
topEndContentUM = topEndContentUM,
bottomEndContentUM = bottomEndContentUM,
promoBannerUM = TangemTokenRowUM.PromoBannerUM.Empty,
tailUM = TangemTokenRowUM.TailUM.Empty,
tailUM = TangemRowTailUM.Empty,
onItemClick = {},
onItemLongClick = {},
)
@ -178,7 +179,7 @@ internal object TangemTokenRowPreviewData {
topEndContentUM = topEndContentUM,
bottomEndContentUM = bottomEndContentUM,
promoBannerUM = TangemTokenRowUM.PromoBannerUM.Empty,
tailUM = TangemTokenRowUM.TailUM.Empty,
tailUM = TangemRowTailUM.Empty,
onItemClick = {},
onItemLongClick = {},
)
@ -189,7 +190,7 @@ internal object TangemTokenRowPreviewData {
headIconUM = coinIconState,
titleUM = titleUM,
subtitleUM = subtitleUM,
tailUM = TangemTokenRowUM.TailUM.Draggable,
tailUM = TangemRowTailUM.Draggable(R.drawable.ic_drag_24),
onItemClick = {},
onItemLongClick = {},
)
@ -202,7 +203,7 @@ internal object TangemTokenRowPreviewData {
subtitleUM = subtitleUM,
topEndContentUM = topEndContentUM,
bottomEndContentUM = bottomEndContentUM,
tailUM = TangemTokenRowUM.TailUM.Draggable,
tailUM = TangemRowTailUM.Draggable(R.drawable.ic_drag_24),
onItemClick = {},
onItemLongClick = {},
)

View file

@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M3.333,14H9.825C9.922,14 10,14.078 10,14.175V20.667M9.949,14.051L3,21"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M20.667,10H14.175C14.078,10 14,9.922 14,9.825V3.333M14.051,9.949L21,3"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
</vector>

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M7,18.759L7,5.5M11.5,10L7.185,5.207C7.086,5.096 6.913,5.096 6.814,5.207L2.5,10M17.314,5L17.314,18.759M12.814,14.259L17.128,19.052C17.228,19.163 17.4,19.163 17.5,19.052L21.814,14.259"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
</vector>

View file

@ -43,4 +43,9 @@ internal data class NorthernLightsStory(
internal data class TangemTokenRowStory(
val isBalanceHidden: Boolean,
val onBalanceHiddenToggle: () -> Unit,
) : StoryBookPage
internal data class TangemHeaderRowStory(
val isBalanceHidden: Boolean,
val onBalanceHiddenToggle: () -> Unit,
) : StoryBookPage

View file

@ -0,0 +1,17 @@
@file:Suppress("MagicNumber", "LongMethod")
package com.tangem.feature.tester.presentation.storybook.page.headerrow
import com.tangem.feature.tester.presentation.storybook.entity.TangemHeaderRowStory
import com.tangem.feature.tester.presentation.storybook.viewmodel.StateUpdater
import com.tangem.feature.tester.presentation.storybook.viewmodel.storyPageFactory
internal fun StateUpdater<TangemHeaderRowStory>.build(): TangemHeaderRowStory {
return TangemHeaderRowStory(
isBalanceHidden = false,
onBalanceHiddenToggle = { updateStory { it.copy(isBalanceHidden = !it.isBalanceHidden) } },
)
}
internal val tangemHeaderRowStoryFactory
get() = storyPageFactory(StateUpdater<TangemHeaderRowStory>::build)

View file

@ -0,0 +1,111 @@
@file:Suppress("MagicNumber", "LongMethod")
package com.tangem.feature.tester.presentation.storybook.page.headerrow
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.ds.row.header.TangemHeaderRow
import com.tangem.core.ui.ds.row.header.TangemHeaderRowUM
import com.tangem.core.ui.ds.row.internal.TangemRowTailUM
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.tester.presentation.storybook.entity.TangemHeaderRowStory
@Composable
internal fun TangemHeaderRowStory(state: TangemHeaderRowStory, modifier: Modifier = Modifier) {
val rows = remember { buildSampleRows() }
LazyColumn(
contentPadding = PaddingValues(bottom = 16.dp),
modifier = modifier
.statusBarsPadding()
.fillMaxSize()
.background(TangemTheme.colors2.surface.level1),
) {
stickyHeader("balance_toggle") {
BalanceToggle(
isHidden = state.isBalanceHidden,
onToggle = state.onBalanceHiddenToggle,
modifier = Modifier
.fillMaxWidth()
.background(TangemTheme.colors2.surface.level1)
.padding(horizontal = 16.dp, vertical = 8.dp),
)
}
items(rows, key = { it.id }) { um ->
TangemHeaderRow(
headerRowUM = um,
isBalanceHidden = state.isBalanceHidden,
modifier = Modifier.background(TangemTheme.colors2.surface.level3),
)
HorizontalDivider(
color = TangemTheme.colors2.border.neutral.secondary,
modifier = Modifier.padding(start = 16.dp),
)
}
}
}
private fun buildSampleRows(): List<TangemHeaderRowUM> = listOf(
TangemHeaderRowUM(
id = "icon_subtitle_no_tail",
startIconUM = TangemIconUM.Currency(currencyIconState = CurrencyIconState.Locked),
tailUM = TangemRowTailUM.Empty,
title = stringReference("Account"),
subtitle = stringReference("\$ 42,900.17"),
),
TangemHeaderRowUM(
id = "icon_subtitle_collapse",
startIconUM = TangemIconUM.Currency(currencyIconState = CurrencyIconState.Locked),
tailUM = TangemRowTailUM.Icon(R.drawable.ic_arrow_collapse_24),
title = stringReference("Account"),
subtitle = stringReference("\$ 42,900.17"),
),
TangemHeaderRowUM(
id = "icon_subtitle_group_drop",
startIconUM = TangemIconUM.Currency(currencyIconState = CurrencyIconState.Locked),
tailUM = TangemRowTailUM.Icon(R.drawable.ic_group_drop_24),
title = stringReference("Account"),
subtitle = stringReference("\$ 42,900.17"),
),
TangemHeaderRowUM(
id = "title_only",
title = stringReference("Account"),
),
)
@Composable
private fun BalanceToggle(isHidden: Boolean, onToggle: () -> Unit, modifier: Modifier = Modifier) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
modifier = modifier,
) {
Text(
text = "isBalanceHidden",
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.secondary,
)
Switch(checked = isHidden, onCheckedChange = { onToggle() })
}
}

View file

@ -1,4 +1,5 @@
@file:Suppress("MagicNumber", "LongMethod")
package com.tangem.feature.tester.presentation.storybook.page.tokenrow
import androidx.compose.foundation.background
@ -44,7 +45,7 @@ internal fun TangemTokenRowStory(state: TangemTokenRowStory, modifier: Modifier
TangemTokenRow(
tokenRowUM = um,
isBalanceHidden = state.isBalanceHidden,
reorderableTokenListState = null,
reorderableState = null,
modifier = Modifier.background(TangemTheme.colors2.surface.level1),
)
HorizontalDivider(

View file

@ -23,6 +23,7 @@ import com.tangem.feature.tester.presentation.storybook.page.message.tangemMessa
import com.tangem.feature.tester.presentation.storybook.page.checkbox.tangemCheckboxStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.tabs.tangemSegmentedPickerStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.tokenrow.tangemTokenRowStoryFactory
import com.tangem.feature.tester.presentation.storybook.page.headerrow.tangemHeaderRowStoryFactory
private data class StoryItem(val title: String, val factory: StoryPageFactory)
@ -35,6 +36,7 @@ private fun buildStories() = listOf(
StoryItem(title = "🗂️ Segmented Picker", factory = tangemSegmentedPickerStoryFactory),
StoryItem(title = "☑️ Checkbox", factory = tangemCheckboxStoryFactory),
StoryItem(title = "🪙 Token Row", factory = tangemTokenRowStoryFactory),
StoryItem(title = "📑 Header Row", factory = tangemHeaderRowStoryFactory),
)
@Composable

View file

@ -11,6 +11,7 @@ import com.tangem.feature.tester.presentation.storybook.entity.TangemBadgeStory
import com.tangem.feature.tester.presentation.storybook.entity.StoryBookUM
import com.tangem.feature.tester.presentation.storybook.entity.StoryList
import com.tangem.feature.tester.presentation.storybook.entity.TangemCheckboxStory
import com.tangem.feature.tester.presentation.storybook.entity.TangemHeaderRowStory
import com.tangem.feature.tester.presentation.storybook.entity.TangemMessageStory
import com.tangem.feature.tester.presentation.storybook.entity.TangemSegmentedPickerStory
import com.tangem.feature.tester.presentation.storybook.entity.TangemTokenRowStory
@ -22,6 +23,7 @@ import com.tangem.feature.tester.presentation.storybook.page.checkbox.TangemChec
import com.tangem.feature.tester.presentation.storybook.page.message.TangemMessageStory
import com.tangem.feature.tester.presentation.storybook.page.tabs.TangemSegmentedPickerStory
import com.tangem.feature.tester.presentation.storybook.page.tokenrow.TangemTokenRowStory
import com.tangem.feature.tester.presentation.storybook.page.headerrow.TangemHeaderRowStory
@Composable
internal fun StoryBookScreen(state: StoryBookUM, modifier: Modifier = Modifier) {
@ -42,6 +44,7 @@ internal fun StoryBookScreen(state: StoryBookUM, modifier: Modifier = Modifier)
is TangemCheckboxStory -> TangemCheckboxStory(state = storyState)
TangemSegmentedPickerStory -> TangemSegmentedPickerStory()
is TangemTokenRowStory -> TangemTokenRowStory(state = storyState)
is TangemHeaderRowStory -> TangemHeaderRowStory(state = storyState)
}
}
}

View file

@ -5,6 +5,7 @@ import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.ds.button.TangemButtonType
import com.tangem.core.ui.ds.button.TangemButtonUM
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.ds.row.internal.TangemRowTailUM
import com.tangem.core.ui.ds.row.token.TangemTokenRowUM
import com.tangem.core.ui.event.consumedEvent
import com.tangem.core.ui.extensions.resourceReference
@ -34,7 +35,7 @@ internal object WalletScreenPreviewData {
text = stringReference("0,12345678 BTC"),
),
promoBannerUM = TangemTokenRowUM.PromoBannerUM.Empty,
tailUM = TangemTokenRowUM.TailUM.Empty,
tailUM = TangemRowTailUM.Empty,
onItemClick = {},
onItemLongClick = {},
)

View file

@ -31,6 +31,7 @@ import com.tangem.core.ui.decorations.roundedShapeItemDecoration
import com.tangem.core.ui.ds.image.TangemIcon
import com.tangem.core.ui.ds.row.header.TangemHeaderRow
import com.tangem.core.ui.ds.row.header.TangemHeaderRowUM
import com.tangem.core.ui.ds.row.internal.TangemRowTailUM
import com.tangem.core.ui.ds.row.token.TangemTokenRow
import com.tangem.core.ui.ds.row.token.TangemTokenRowUM
import com.tangem.core.ui.ds.row.token.internal.TokenRowTitle
@ -146,7 +147,7 @@ private fun LazyListScope.tokenItem(
is TangemTokenRowUM -> TangemTokenRow(
tokenRowUM = tokenRowUM,
isBalanceHidden = isBalanceHidden,
reorderableTokenListState = null,
reorderableState = null,
modifier = itemModifier,
)
is TangemHeaderRowUM -> TangemHeaderRow(
@ -199,7 +200,7 @@ private fun LazyListScope.portfolioItem(
is TangemTokenRowUM -> TangemTokenRow(
tokenRowUM = tokenRowUM,
isBalanceHidden = isBalanceHidden,
reorderableTokenListState = null,
reorderableState = null,
modifier = itemModifier,
)
is TangemHeaderRowUM -> TangemHeaderRow(
@ -368,7 +369,7 @@ internal fun PortfolioRowItem(
?.text?.orMaskWithStars(isBalanceHidden),
titleContent = composables.title,
headContent = composables.icon,
footerTangemIconRes = R.drawable.ic_minimize_24,
tailUM = TangemRowTailUM.Icon(R.drawable.ic_minimize_24),
onItemClick = item.tokenRowUM.onItemClick,
)
} else {
@ -377,7 +378,7 @@ internal fun PortfolioRowItem(
headComponent = composables.icon,
titleComponent = composables.title,
isBalanceHidden = isBalanceHidden,
reorderableTokenListState = null,
reorderableState = null,
)
}
}