Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-28 14:08:01 +03:00
commit 06a915a0f4
2186 changed files with 101417 additions and 36593 deletions

View file

@ -1,3 +1,4 @@
import java.io.ByteArrayOutputStream
import java.security.MessageDigest
plugins {
@ -20,6 +21,10 @@ abstract class VerifyDesignTokensTask : DefaultTask() {
@get:PathSensitive(PathSensitivity.RELATIVE)
abstract val iconsDir: DirectoryProperty
@get:InputDirectory
@get:PathSensitive(PathSensitivity.RELATIVE)
abstract val assetsDir: DirectoryProperty
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
abstract val hashFile: RegularFileProperty
@ -47,29 +52,38 @@ abstract class VerifyDesignTokensTask : DefaultTask() {
"Run: git submodule update --init --recursive"
}
val assetsDirValue = assetsDir.get().asFile
require(assetsDirValue.exists() && assetsDirValue.isDirectory) {
"ds-tokens assets folder not found: ${assetsDirValue.absolutePath}\n" +
"Run: git submodule update --init --recursive"
}
val tokensInputHash = hashTreeHex(tokensDirValue, "json")
val iconsHash = hashTreeHex(iconsDirValue, "svg")
val assetsHash = hashTreeHex(assetsDirValue, "svg")
// Mirror build-tokens.mjs: sha256(tokensInputHash + 0x00 + iconsHash), all hex strings.
// Mirror build-tokens.mjs: sha256(tokensInputHash + 0x00 + iconsHash + 0x00 + assetsHash).
val outer = MessageDigest.getInstance("SHA-256")
outer.update(tokensInputHash.toByteArray())
outer.update(0)
outer.update(iconsHash.toByteArray())
outer.update(0)
outer.update(assetsHash.toByteArray())
val actual = outer.digest()
.joinToString("") { b: Byte -> b.toInt().and(0xFF).toString(16).padStart(2, '0') }
val expected = hashFileValue.readText().trim()
require(actual == expected) {
"Design tokens are out of date!\n" +
" ds-tokens hash: $actual\n" +
" generated hash: $expected\n" +
" computed from ds-tokens: $actual\n" +
" committed .tokens-hash: $expected\n" +
"Run the token generator: cd core/ui/token-gen && npm run build"
}
stampFile.get().asFile.writeText(actual)
}
private fun hashTreeHex(root: java.io.File, extension: String): String {
private fun hashTreeHex(root: File, extension: String): String {
val digest = MessageDigest.getInstance("SHA-256")
val files = root.walkTopDown()
.filter { it.isFile && it.extension == extension }
@ -79,12 +93,27 @@ abstract class VerifyDesignTokensTask : DefaultTask() {
for (file in files) {
digest.update(file.relativeTo(root).invariantSeparatorsPath.toByteArray())
digest.update(nul)
digest.update(file.readBytes())
digest.update(file.readBytes().stripCr())
digest.update(nul)
}
return digest.digest()
.joinToString("") { b: Byte -> b.toInt().and(0xFF).toString(16).padStart(2, '0') }
}
/**
* Strips CR (0x0D) bytes so the token hash ignores CRLF vs LF line endings. The ds-tokens
* submodule is not covered by this repo's .gitattributes, so its .json/.svg sources may be
* checked out with CRLF on some platforms; without this the verification is non-deterministic.
* Removes lone CRs too — safe for UTF-8 sources, where 0x0D never appears inside a
* multi-byte sequence. Must stay byte-for-byte identical to stripCr() in token-gen/hash-util.mjs.
*/
private fun ByteArray.stripCr(): ByteArray {
val cr: Byte = 0x0D
if (none { it == cr }) return this
val out = ByteArrayOutputStream(size)
for (b in this) if (b != cr) out.write(b.toInt())
return out.toByteArray()
}
}
android {
namespace = "com.tangem.core.ui"
@ -100,6 +129,7 @@ android {
val verifyDesignTokens = tasks.register<VerifyDesignTokensTask>("verifyDesignTokens") {
tokensDir.set(file("ds-tokens/tokens"))
iconsDir.set(file("ds-tokens/icons"))
assetsDir.set(file("ds-tokens/assets"))
hashFile.set(file("src/main/java/com/tangem/core/ui/res/generated/.tokens-hash"))
stampFile.set(layout.buildDirectory.file("tokens-verified.stamp"))
}
@ -109,51 +139,53 @@ tasks.named("preBuild") {
}
dependencies {
/** Project - Domain */
implementation(projects.domain.appTheme.models)
implementation(projects.domain.express.models)
implementation(projects.domain.models)
implementation(projects.domain.tokens.models)
/** Project - Core */
implementation(projects.core.res)
implementation(projects.core.utils)
api(projects.core.decompose)
implementation(projects.core.error)
// region DI
implementation(deps.hilt.android)
// endregion
/** AndroidX libraries */
implementation(deps.androidx.fragment.ktx)
// region Kotlin
api(deps.kotlin.coroutines)
api(deps.kotlin.immutable.collections)
api(deps.kotlin.serialization.core)
// endregion
// region Compose
implementation(deps.compose.accompanist.permission)
api(deps.compose.accompanist.systemUiController)
api(deps.compose.coil)
implementation(deps.compose.constraintLayout)
api(deps.compose.foundation)
api(deps.compose.material3)
api(deps.compose.paging)
api(deps.compose.reorderable)
api(deps.compose.shimmer)
implementation(deps.compose.ui.tooling)
implementation(deps.compose.ui.utils)
// endregion
// region AndroidX
api(deps.androidx.activity)
implementation(deps.androidx.activity.compose)
implementation(deps.androidx.annotation)
implementation(deps.androidx.appCompat)
implementation(deps.androidx.core)
implementation(deps.androidx.core.ktx)
implementation(deps.androidx.paging.runtime)
implementation(deps.lifecycle.runtime.ktx)
implementation(deps.androidx.palette)
api(deps.androidx.palette)
implementation(deps.androidx.savedState)
implementation(deps.androidx.windowManager) {
exclude(
deps.kotlin.coroutines.android.get().module.group,
deps.kotlin.coroutines.android.get().module.name
deps.kotlin.coroutines.android.get().module.name,
)
}
api(deps.lifecycle.compose)
api(deps.lifecycle.runtime.ktx)
// endregion
/** Compose */
implementation(deps.compose.constraintLayout)
implementation(deps.compose.foundation)
implementation(deps.compose.material3)
implementation(deps.compose.paging)
implementation(deps.compose.ui.tooling)
implementation(deps.compose.ui.utils)
implementation(deps.compose.coil)
implementation(deps.compose.navigation)
implementation(deps.compose.navigation.hilt)
api(deps.compose.reorderable)
/** Other libraries */
implementation(deps.compose.accompanist.systemUiController)
implementation(deps.compose.accompanist.permission)
implementation(deps.material)
implementation(deps.compose.shimmer)
implementation(deps.kotlin.immutable.collections)
implementation(deps.zxing.qrCore)
api(deps.jodatime)
implementation(deps.markdown)
// region Other libraries
api(deps.arrow.core)
api(deps.haze) {
exclude(module = "activity-compose")
exclude(module = "activity")
@ -164,9 +196,28 @@ dependencies {
exclude(module = "activity")
exclude(module = "activity-ktx")
}
api(deps.jodatime)
api(deps.markdown)
implementation(deps.material)
implementation(deps.zxing.qrCore)
// endregion
/** Tests */
// region Core modules
api(projects.core.decompose)
api(projects.core.error)
implementation(projects.core.res)
implementation(projects.core.utils)
// endregion
// region Domain models
api(projects.domain.appTheme.models)
api(projects.domain.express.models)
api(projects.domain.models)
// endregion
// region Tests
testImplementation(deps.test.junit5)
testImplementation(deps.test.mockk)
testImplementation(deps.test.truth)
testImplementation(deps.test.junit5)
// endregion
}

@ -1 +1 @@
Subproject commit 42aac70c1d2d0d636470fa476703cab353010bba
Subproject commit a59c6a363903575d12ac7a6991ae76b60e064cd1

View file

@ -1,7 +0,0 @@
package com.tangem.core.ui
interface DesignFeatureToggles {
val isRedesignEnabled: Boolean
val isWarningsRefactoringEnabled: Boolean
}

View file

@ -19,6 +19,4 @@ interface UiDependencies {
val globalTopSnackbarHostState: TangemTopSnackbarHostState
val eventMessageHandler: EventMessageHandler
val designFeatureToggles: DesignFeatureToggles
}

View file

@ -10,44 +10,15 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
import com.tangem.core.ui.components.buttons.SecondarySmallButton
import com.tangem.core.ui.components.buttons.SmallButtonConfig
import com.tangem.core.ui.ds.button.*
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.res.TangemThemePreviewRedesign
@Composable
fun UnableToLoadData(onRetryClick: () -> Unit, modifier: Modifier = Modifier) {
if (LocalRedesignEnabled.current) {
UnableToLoadDataV2(onRetryClick, modifier)
} else {
UnableToLoadDataV1(onRetryClick, modifier)
}
}
@Composable
private fun UnableToLoadDataV1(onRetryClick: () -> Unit, modifier: Modifier = Modifier) {
Column(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = stringResourceSafe(R.string.markets_loading_error_title),
style = TangemTheme.typography.caption1,
color = TangemTheme.colors.text.tertiary,
)
SecondarySmallButton(
config = SmallButtonConfig(
text = resourceReference(R.string.try_to_load_data_again_button_title),
onClick = onRetryClick,
),
)
}
UnableToLoadDataV2(onRetryClick, modifier)
}
@Composable
@ -80,13 +51,4 @@ private fun PreviewV2() {
TangemThemePreviewRedesign {
UnableToLoadDataV2(onRetryClick = {})
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun PreviewV1() {
TangemThemePreview {
UnableToLoadDataV1(onRetryClick = {})
}
}

View file

@ -32,7 +32,15 @@ import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.res.TangemThemePreviewRedesign
enum class AccountIconSize {
Default, Large, Medium, Small, ExtraSmall, RedesignedDefault, RedesignExtraSmall
Default,
Large,
Medium,
Small,
ExtraSmall,
RedesignedDefault,
RedesignExtraSmall,
ContactLarge,
ContactDefault,
}
/**
@ -132,6 +140,8 @@ fun AccountCharIcon(char: Char, color: Color, size: AccountIconSize, modifier: M
AccountIconSize.ExtraSmall -> TangemTheme.typography.caption1
AccountIconSize.RedesignedDefault -> TangemTheme.typography2.headingSemibold28
AccountIconSize.RedesignExtraSmall -> TangemTheme.typography2.captionMedium11
AccountIconSize.ContactLarge -> TangemTheme.typography3.heading.medium
AccountIconSize.ContactDefault -> TangemTheme.typography3.body.medium
}
val textSize by animateFloatAsState(
@ -166,6 +176,8 @@ private fun AccountIconSize.iconSizeInDp(): Dp = when (this) {
AccountIconSize.ExtraSmall -> 8.dp
AccountIconSize.RedesignedDefault -> 20.dp
AccountIconSize.RedesignExtraSmall -> 8.dp
AccountIconSize.ContactLarge -> 32.dp
AccountIconSize.ContactDefault -> 20.dp
}
fun AccountIconSize.toBoxSize(): Dp = when (this) {
@ -176,6 +188,8 @@ fun AccountIconSize.toBoxSize(): Dp = when (this) {
AccountIconSize.ExtraSmall -> 14.dp
AccountIconSize.RedesignedDefault -> 40.dp
AccountIconSize.RedesignExtraSmall -> 16.dp
AccountIconSize.ContactLarge -> 80.dp
AccountIconSize.ContactDefault -> 40.dp
}
private fun AccountIconSize.boxShapeSizeInDp(): Dp = when (this) {
@ -186,6 +200,8 @@ private fun AccountIconSize.boxShapeSizeInDp(): Dp = when (this) {
AccountIconSize.ExtraSmall -> 4.dp
AccountIconSize.RedesignedDefault -> 12.dp
AccountIconSize.RedesignExtraSmall -> 6.dp
AccountIconSize.ContactLarge -> 80.dp
AccountIconSize.ContactDefault -> 100.dp
}
@Preview(showBackground = true)
@ -228,7 +244,9 @@ private fun Sample() {
AccountIconSize.Small -> AccountIconSize.ExtraSmall
AccountIconSize.ExtraSmall -> AccountIconSize.RedesignedDefault
AccountIconSize.RedesignedDefault -> AccountIconSize.RedesignExtraSmall
AccountIconSize.RedesignExtraSmall -> AccountIconSize.Default
AccountIconSize.RedesignExtraSmall -> AccountIconSize.ContactLarge
AccountIconSize.ContactLarge -> AccountIconSize.ContactDefault
AccountIconSize.ContactDefault -> AccountIconSize.Default
}
}) { Text("Change") }

View file

@ -36,12 +36,10 @@ import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheetDraggab
import com.tangem.core.ui.components.sheetscaffold.TangemSheetState
import com.tangem.core.ui.components.sheetscaffold.TangemSheetValue
import com.tangem.core.ui.components.sheetscaffold.rememberSheetState
import com.tangem.core.ui.res.LocalBottomSheetAlwaysVisible
import com.tangem.core.ui.res.LocalWindowSize
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.res.*
import com.tangem.core.ui.test.BaseBottomSheetTestTags
import com.tangem.core.ui.utils.WindowInsetsZero
import dev.chrisbanes.haze.rememberHazeState
/**
* Extra bottom inset that scrollable content under a [BasicBottomSheet] should reserve so it
@ -235,46 +233,48 @@ inline fun <reified T : TangemBottomSheetConfigContent> BasicBottomSheet(
}
val bsContent: @Composable ColumnScope.() -> Unit = {
val contentModifier = when (type) {
Default -> Modifier
.clip(
RoundedCornerShape(
topStart = TangemTheme.dimens2.x8,
topEnd = TangemTheme.dimens2.x8,
),
)
Modal -> Modifier
.padding(
start = TangemTheme.dimens2.x2,
end = TangemTheme.dimens2.x2,
bottom = bottomBarHeight,
)
.clip(RoundedCornerShape(TangemTheme.dimens2.x8))
}
Column(
modifier = contentModifier
.background(containerColor)
.heightIn(max = maxHeight)
.testTag(BaseBottomSheetTestTags.CONTAINER),
) {
Box(modifier = Modifier.fillMaxWidth()) {
title(model)
}
Box(modifier = Modifier.fillMaxWidth()) {
if (footer != null) {
FooterOverlay(
measuredFooterHeight = footerHeightDp,
onMeasureFooter = { newHeight ->
if (newHeight != footerHeightDp) {
footerHeightDp = newHeight
}
},
footer = { footer(model) },
content = { content(model) },
CompositionLocalProvider(LocalHazeState provides rememberHazeState()) {
val contentModifier = when (type) {
Default -> Modifier
.clip(
RoundedCornerShape(
topStart = TangemTheme.dimens2.x8,
topEnd = TangemTheme.dimens2.x8,
),
)
} else {
content(model)
Modal -> Modifier
.padding(
start = TangemTheme.dimens2.x2,
end = TangemTheme.dimens2.x2,
bottom = bottomBarHeight,
)
.clip(RoundedCornerShape(TangemTheme.dimens2.x8))
}
Column(
modifier = contentModifier
.background(containerColor)
.heightIn(max = maxHeight)
.testTag(BaseBottomSheetTestTags.CONTAINER),
) {
Box(modifier = Modifier.fillMaxWidth()) {
title(model)
}
Box(modifier = Modifier.fillMaxWidth()) {
if (footer != null) {
FooterOverlay(
measuredFooterHeight = footerHeightDp,
onMeasureFooter = { newHeight ->
if (newHeight != footerHeightDp) {
footerHeightDp = newHeight
}
},
footer = { footer(model) },
content = { content(model) },
)
} else {
content(model)
}
}
}
}

View file

@ -2,22 +2,13 @@ package com.tangem.core.ui.components.bottomsheets.message
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.tangem.core.ui.res.LocalRedesignEnabled
@Composable
fun MessageBottomSheet(state: MessageBottomSheetUM, onDismissRequest: () -> Unit) {
if (LocalRedesignEnabled.current) {
MessageBottomSheetV2(state, onDismissRequest)
} else {
MessageBottomSheetV1(state, onDismissRequest)
}
MessageBottomSheetV2(state, onDismissRequest)
}
@Composable
fun MessageBottomSheetContent(state: MessageBottomSheetUM, modifier: Modifier = Modifier) {
if (LocalRedesignEnabled.current) {
MessageBottomSheetContentV2(state, modifier)
} else {
MessageBottomSheetContentV1(state, modifier)
}
MessageBottomSheetContentV2(state, modifier)
}

View file

@ -63,6 +63,7 @@ fun MessageBottomSheetV2(state: MessageBottomSheetUM, onDismissRequest: () -> Un
type = TangemTopBarType.BottomSheet,
endContent = {
TangemButton(
modifier = Modifier.testTag(WarningBottomSheetTestTags.CLOSE_BUTTON),
iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_24),
onClick = stateWithOnDismiss.onDismissRequest,
size = TangemButton.Size.X11,

View file

@ -21,6 +21,7 @@ import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
import com.tangem.core.ui.components.*
@ -38,6 +39,9 @@ import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.utils.WindowInsetsZero
import com.tangem.core.ui.utils.toPx
/** Default reserved height for the [TangemModalBottomSheetWithFooter] footer slot. */
val DEFAULT_FOOTER_HEIGHT: Dp = 80.dp
/**
* Modal bottom sheet with [content], [footer] and optional [title].
*
@ -50,6 +54,12 @@ inline fun <reified T : TangemBottomSheetConfigContent> TangemModalBottomSheetWi
config: TangemBottomSheetConfig,
containerColor: Color = TangemTheme.colors.background.primary,
skipPartiallyExpanded: Boolean = true,
// FIXME([REDACTED_TASK_KEY]): temp workaround
// The footer slot reserves a fixed [DEFAULT_FOOTER_HEIGHT];
// callers whose footer differs must pass the real height explicitly. Exposed as an opt-in
// parameter so existing usages keep the previous behavior and nothing else is affected.
// Rework so the sheet measures the actual footer height internally and drops this parameter.
footerHeight: Dp = DEFAULT_FOOTER_HEIGHT,
noinline onBack: (() -> Unit)? = null,
crossinline title: @Composable BoxScope.(T) -> Unit = {},
crossinline content: @Composable (T) -> Unit,
@ -65,6 +75,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> TangemModalBottomSheetWi
content = content,
footer = footer,
skipPartiallyExpanded = skipPartiallyExpanded,
footerHeight = footerHeight,
)
} else {
DefaultModalBottomSheetWithFooter<T>(
@ -75,6 +86,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> TangemModalBottomSheetWi
footer = footer,
onBack = onBack,
skipPartiallyExpanded = skipPartiallyExpanded,
footerHeight = footerHeight,
)
}
}
@ -85,6 +97,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> DefaultModalBottomSheetW
config: TangemBottomSheetConfig,
containerColor: Color,
skipPartiallyExpanded: Boolean = true,
footerHeight: Dp = DEFAULT_FOOTER_HEIGHT,
noinline onBack: (() -> Unit)? = null,
crossinline title: @Composable BoxScope.(T) -> Unit,
crossinline content: @Composable (T) -> Unit,
@ -117,6 +130,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> DefaultModalBottomSheetW
onBack = onBack,
content = content,
footer = footer,
footerHeight = footerHeight,
)
}
@ -135,6 +149,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> PreviewModalBottomSheetW
config: TangemBottomSheetConfig,
containerColor: Color,
skipPartiallyExpanded: Boolean = true,
footerHeight: Dp = DEFAULT_FOOTER_HEIGHT,
crossinline title: @Composable BoxScope.(T) -> Unit,
crossinline content: @Composable (T) -> Unit,
noinline footer: @Composable (BoxScope.(T) -> Unit)?,
@ -150,6 +165,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> PreviewModalBottomSheetW
title = title,
content = content,
footer = footer,
footerHeight = footerHeight,
)
}
@ -161,6 +177,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> BasicModalBottomSheetWit
sheetState: TangemSheetState,
containerColor: Color,
modifier: Modifier = Modifier,
footerHeight: Dp = DEFAULT_FOOTER_HEIGHT,
noinline onBack: (() -> Unit)? = null,
crossinline title: @Composable BoxScope.(T) -> Unit,
crossinline content: @Composable (T) -> Unit,
@ -178,7 +195,8 @@ inline fun <reified T : TangemBottomSheetConfigContent> BasicModalBottomSheetWit
val isKeyboardOpen by rememberIsKeyboardVisible()
val buttonHeight by animateDpAsState(
targetValue = if (footer != null) 80.dp else 0.dp,
targetValue = if (footer != null) footerHeight else 0.dp,
label = "FooterHeight",
)
// Offset calculation for keyboard scroll adjustment:
// 1) Button height (footer)

View file

@ -19,7 +19,6 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.CircleShimmer
import com.tangem.core.ui.extensions.conditional
import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.TokenElementsTestTags
import com.tangem.core.ui.utils.getGreyScaleColorFilter
@ -51,11 +50,7 @@ fun TangemCurrencyIcon(state: CurrencyIconState, modifier: Modifier = Modifier,
modifier = iconModifier,
shouldShowTopBadge = shouldDisplayNetwork,
networkBadgeSize = 14.dp,
networkBadgeBackground = if (LocalRedesignEnabled.current) {
TangemTheme.colors2.surface.level1
} else {
TangemTheme.colors.background.primary
},
networkBadgeBackground = TangemTheme.colors2.surface.level1,
)
}
}

View file

@ -7,10 +7,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
@ -21,7 +19,6 @@ 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.extensions.stringResourceSafe
import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.res.TangemThemePreviewRedesign
@ -34,67 +31,13 @@ fun DescriptionItem(
hasFullDescription: Boolean,
onReadMoreClick: () -> Unit,
modifier: Modifier = Modifier,
textStyle: TextStyle = TangemTheme.typography.body2,
) {
if (LocalRedesignEnabled.current) {
DescriptionItemV2(
description = description,
hasFullDescription = hasFullDescription,
onReadMoreClick = onReadMoreClick,
modifier = modifier,
)
} else {
DescriptionItemV1(
description = description,
hasFullDescription = hasFullDescription,
onReadMoreClick = onReadMoreClick,
modifier = modifier,
textStyle = textStyle,
)
}
}
@Composable
private fun DescriptionItemV1(
description: TextReference,
hasFullDescription: Boolean,
onReadMoreClick: () -> Unit,
modifier: Modifier = Modifier,
textStyle: TextStyle = TangemTheme.typography.body2,
) {
if (hasFullDescription) {
val text = buildAnnotatedString {
withStyle(SpanStyle(color = TangemTheme.colors.text.secondary)) {
append(description.resolveReference())
}
withStyle(SpanStyle(color = TangemTheme.colors.text.accent)) {
append(
" " + stringResourceSafe(R.string.common_read_more).replace(
' ',
StringsSigns.NON_BREAKING_SPACE,
),
)
}
}
Text(
modifier = modifier
.clickable(
interactionSource = null,
indication = null,
onClick = onReadMoreClick,
),
text = text,
style = textStyle,
)
} else {
Text(
modifier = modifier,
text = description.resolveReference(),
style = textStyle,
color = TangemTheme.colors.text.secondary,
)
}
DescriptionItemV2(
description = description,
hasFullDescription = hasFullDescription,
onReadMoreClick = onReadMoreClick,
modifier = modifier,
)
}
@Composable
@ -141,34 +84,7 @@ private fun DescriptionItemV2(
@Composable
fun DescriptionPlaceholder(modifier: Modifier = Modifier) {
if (LocalRedesignEnabled.current) {
DescriptionPlaceholderV2(modifier)
} else {
DescriptionPlaceholderV1(modifier)
}
}
@Composable
private fun DescriptionPlaceholderV1(modifier: Modifier = Modifier) {
Column(
modifier = modifier,
) {
TextShimmer(
modifier = Modifier.fillMaxWidth(),
style = TangemTheme.typography.body2,
textSizeHeight = true,
)
TextShimmer(
modifier = Modifier.fillMaxWidth(),
style = TangemTheme.typography.body2,
textSizeHeight = true,
)
TextShimmer(
modifier = Modifier.fillMaxWidth(fraction = 0.8f),
style = TangemTheme.typography.body2,
textSizeHeight = true,
)
}
DescriptionPlaceholderV2(modifier)
}
@Composable
@ -213,17 +129,15 @@ private fun ContentPreviewV1() {
@Preview
@Composable
private fun ContentPreviewV2() {
CompositionLocalProvider(LocalRedesignEnabled provides true) {
TangemThemePreviewRedesign {
DescriptionItem(
description = stringReference(
"XRP (XRP) is a cryptocurrency launched in January 2009, where the first " +
"genesis block was mined on 9th January 2009",
),
hasFullDescription = true,
onReadMoreClick = {},
)
}
TangemThemePreviewRedesign {
DescriptionItem(
description = stringReference(
"XRP (XRP) is a cryptocurrency launched in January 2009, where the first " +
"genesis block was mined on 9th January 2009",
),
hasFullDescription = true,
onReadMoreClick = {},
)
}
}
@ -245,16 +159,14 @@ private fun PreviewPlaceholderV1() {
@Preview
@Composable
private fun PreviewPlaceholderV2() {
CompositionLocalProvider(LocalRedesignEnabled provides true) {
TangemThemePreviewRedesign {
PreviewShimmerContainer(
actualContent = {
ContentPreviewV2()
},
shimmerContent = {
DescriptionPlaceholder()
},
)
}
TangemThemePreviewRedesign {
PreviewShimmerContainer(
actualContent = {
ContentPreviewV2()
},
shimmerContent = {
DescriptionPlaceholder()
},
)
}
}

View file

@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.*
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
@ -14,7 +13,6 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.R
import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.res.TangemThemePreviewRedesign
@ -27,72 +25,13 @@ fun PriceChangeInPercent(
modifier: Modifier = Modifier,
isDisabled: Boolean = false,
) {
if (LocalRedesignEnabled.current) {
PriceChangeInPercentV2(
modifier = modifier,
valueInPercent = valueInPercent,
type = type,
textStyle = textStyle,
isDisabled = isDisabled,
)
} else {
PriceChangeInPercentV1(
modifier = modifier,
valueInPercent = valueInPercent,
type = type,
textStyle = textStyle,
)
}
}
@Composable
private fun PriceChangeInPercentV1(
valueInPercent: String,
type: PriceChangeType,
textStyle: TextStyle,
modifier: Modifier = Modifier,
) {
if (valueInPercent.isBlank()) {
Box(modifier)
return
}
Row(
PriceChangeInPercentV2(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing2),
) {
Icon(
modifier = Modifier
.size(TangemTheme.dimens.size8)
.align(Alignment.CenterVertically),
imageVector = ImageVector.vectorResource(
id = when (type) {
PriceChangeType.UP -> R.drawable.ic_arrow_up_8
PriceChangeType.DOWN -> R.drawable.ic_arrow_down_8
PriceChangeType.NEUTRAL -> R.drawable.ic_elipse_8
},
),
tint = when (type) {
PriceChangeType.UP -> TangemTheme.colors.icon.accent
PriceChangeType.DOWN -> TangemTheme.colors.icon.warning
PriceChangeType.NEUTRAL -> TangemTheme.colors.icon.inactive
},
contentDescription = null,
)
Text(
text = valueInPercent,
color = when (type) {
PriceChangeType.UP -> TangemTheme.colors.text.accent
PriceChangeType.DOWN -> TangemTheme.colors.text.warning
PriceChangeType.NEUTRAL -> TangemTheme.colors.text.disabled
},
style = textStyle,
overflow = TextOverflow.Visible,
maxLines = 1,
)
}
valueInPercent = valueInPercent,
type = type,
textStyle = textStyle,
isDisabled = isDisabled,
)
}
@Composable
@ -191,31 +130,29 @@ private fun PreviewV1() {
@Composable
private fun PreviewV2() {
TangemThemePreviewRedesign {
CompositionLocalProvider(LocalRedesignEnabled provides true) {
Column {
PriceChangeInPercent(
valueInPercent = "52.00%",
type = PriceChangeType.NEUTRAL,
textStyle = TangemTheme.typography2.captionRegular12,
)
PriceChangeInPercent(
valueInPercent = "52.00%",
type = PriceChangeType.UP,
textStyle = TangemTheme.typography2.captionRegular12,
isDisabled = true,
)
PriceChangeInPercent(
valueInPercent = "52.00%",
type = PriceChangeType.DOWN,
textStyle = TangemTheme.typography2.captionRegular12,
isDisabled = false,
)
PriceChangeInPercent(
valueInPercent = "52.00%",
type = PriceChangeType.DOWN,
textStyle = TangemTheme.typography2.captionRegular12,
)
}
Column {
PriceChangeInPercent(
valueInPercent = "52.00%",
type = PriceChangeType.NEUTRAL,
textStyle = TangemTheme.typography2.captionRegular12,
)
PriceChangeInPercent(
valueInPercent = "52.00%",
type = PriceChangeType.UP,
textStyle = TangemTheme.typography2.captionRegular12,
isDisabled = true,
)
PriceChangeInPercent(
valueInPercent = "52.00%",
type = PriceChangeType.DOWN,
textStyle = TangemTheme.typography2.captionRegular12,
isDisabled = false,
)
PriceChangeInPercent(
valueInPercent = "52.00%",
type = PriceChangeType.DOWN,
textStyle = TangemTheme.typography2.captionRegular12,
)
}
}
}

View file

@ -51,7 +51,10 @@ inline fun <reified T : StoryConfig> StoriesContainer(
) {
var watchedCounter by remember { mutableIntStateOf(1) }
var isPressed by remember { mutableStateOf(value = false) }
val storyState by remember(config) {
// Key on content (stories + repeatability), not the whole config object: an unrelated change
// to the config instance (e.g. a caller folding a changing flag into it) must not recreate the
// state machine and rewind stories to the first page.
val storyState by remember(config.stories, config.isRestartable) {
mutableStateOf(
StoriesStepStateMachine(
stories = config.stories,
@ -59,7 +62,9 @@ inline fun <reified T : StoryConfig> StoriesContainer(
),
)
}
BackHandler(onBack = { config.onClose(watchedCounter) })
if (config.isCloseButtonVisible) {
BackHandler(onBack = { config.onClose(watchedCounter) })
}
val isPaused = isPressed || isPauseStories
@ -90,22 +95,24 @@ inline fun <reified T : StoryConfig> StoriesContainer(
paused = isPaused,
onStepFinish = onNextClick,
)
Icon(
painter = rememberVectorPainter(
image = ImageVector.vectorResource(R.drawable.ic_close_24),
),
tint = TangemTheme.colors.icon.constant,
contentDescription = null,
modifier = Modifier
.align(Alignment.End)
.padding(top = 14.dp, end = 16.dp)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = LocalIndication.current,
onClick = { config.onClose(watchedCounter) },
)
.testTag(SwapStoriesScreenTestTags.CLOSE_BUTTON),
)
if (config.isCloseButtonVisible) {
Icon(
painter = rememberVectorPainter(
image = ImageVector.vectorResource(R.drawable.ic_close_24),
),
tint = TangemTheme.colors.icon.constant,
contentDescription = null,
modifier = Modifier
.align(Alignment.End)
.padding(top = 14.dp, end = 16.dp)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = LocalIndication.current,
onClick = { config.onClose(watchedCounter) },
)
.testTag(SwapStoriesScreenTestTags.CLOSE_BUTTON),
)
}
}
}
}

View file

@ -5,13 +5,18 @@ import kotlinx.collections.immutable.ImmutableList
/**
* Config for stories component
*
* @property stories configuration list
* @property stories configuration list
* @property isRestartable indicates than stories progressions starts
* @property isCloseButtonVisible whether the top-right close button (and back handler) is shown.
* Set `false` for non-closable stories (e.g. a root intro screen); [onClose] is then irrelevant.
* @property onClose invoked with the number of watched stories when the user closes them.
* Only meaningful when [isCloseButtonVisible] is `true`; defaults to a no-op for non-closable stories.
*/
interface StoriesContentConfig<T : StoryConfig> {
val stories: ImmutableList<T>
val isRestartable: Boolean
val onClose: (Int) -> Unit
val isCloseButtonVisible: Boolean get() = true
val onClose: (Int) -> Unit get() = {}
}
interface StoryConfig {

View file

@ -3,7 +3,9 @@ package com.tangem.core.ui.components.text
import android.content.res.Configuration
import androidx.compose.animation.core.*
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.*
@ -38,22 +40,14 @@ fun rememberBladeAnimation(): BladeAnimation {
@Suppress("MagicNumber")
@Composable
fun TextStyle.applyBladeBrush(isEnabled: Boolean, textColor: Color): TextStyle {
val offsetState = LocalBladeAnimation.current.offsetState
val offset = if (isEnabled) offsetState.value else 0f
if (!isEnabled) return this.copy(color = textColor)
val brush = remember(offset, textColor, isEnabled) {
val offsetState = LocalBladeAnimation.current.offsetState
val offset = offsetState.value
val brush = remember(offset, textColor) {
object : ShaderBrush() {
override fun createShader(size: Size): Shader {
if (!isEnabled) {
// Solid color via the same shader path (LinearGradientShader needs >= 2 colors).
return LinearGradientShader(
colors = listOf(textColor, textColor),
from = Offset.Zero,
to = Offset(size.width, size.height),
tileMode = TileMode.Clamp,
)
}
val center = Offset(size.width / 2f, size.height / 2f)
val diagonal = sqrt(size.width * size.width + size.height * size.height)
// Subtle diagonal angle, similar to iOS shimmer

View file

@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
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
@ -32,11 +33,15 @@ import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.R
import com.tangem.core.ui.components.currency.icon.CurrencyIcon
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.components.icons.identicon.IdentIcon
import com.tangem.core.ui.components.transactions.state.TransactionItemUM
import com.tangem.core.ui.components.transactions.state.TransactionItemUM.Content.Direction
import com.tangem.core.ui.components.transactions.state.TransactionItemUM.Content.Status
import com.tangem.core.ui.components.transactions.state.TransactionItemUM.ContentSubtitle
import com.tangem.core.ui.components.transactions.state.TxIcon
import com.tangem.core.ui.components.transactions.state.asImageVector
import com.tangem.core.ui.ds.image.TangemDeviceIcon
import com.tangem.core.ui.ds.row.TangemRowContainer
import com.tangem.core.ui.ds.row.TangemRowLayoutId
@ -47,6 +52,12 @@ import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.res.generated.icons.Icons
import com.tangem.core.ui.res.generated.icons.ic_arrow_down_20
import com.tangem.core.ui.res.generated.icons.ic_arrow_swap_horizontal_20
import com.tangem.core.ui.res.generated.icons.ic_arrow_up_20
import com.tangem.core.ui.res.generated.icons.ic_card_20
import com.tangem.core.ui.res.generated.icons.ic_cross_20
import com.tangem.core.ui.test.TransactionHistoryItemTestTags
@Composable
@ -70,55 +81,92 @@ fun TransactionItem(state: TransactionItemUM, isBalanceHidden: Boolean, modifier
@Composable
private fun ContentItem(state: TransactionItemUM.Content, isBalanceHidden: Boolean, modifier: Modifier = Modifier) {
val rowModifier = modifier
.fillMaxWidth()
.clickable(onClick = state.onClick)
.testTag(TransactionHistoryItemTestTags.ITEM)
TangemRowContainer(
modifier = rowModifier,
contentPadding = PaddingValues(
horizontal = TangemTheme.dimens2.x4,
vertical = TangemTheme.dimens2.x3,
),
Column(
modifier = modifier
.fillMaxWidth()
.clickable(onClick = state.onClick)
.testTag(TransactionHistoryItemTestTags.ITEM),
) {
StatusCircle(
iconRes = state.iconRes,
status = state.status,
modifier = Modifier
.layoutId(TangemRowLayoutId.HEAD)
.padding(end = TangemTheme.dimens2.x3)
.size(TangemTheme.dimens2.x10)
.testTag(TransactionHistoryItemTestTags.STATUS_PREFIX + state.status.testTagSuffix),
TangemRowContainer(
contentPadding = PaddingValues(
horizontal = TangemTheme.dimens2.x4,
vertical = TangemTheme.dimens2.x3,
),
) {
StatusCircle(
icon = state.icon,
status = state.status,
modifier = Modifier
.layoutId(TangemRowLayoutId.HEAD)
.padding(end = TangemTheme.dimens2.x3)
.size(TangemTheme.dimens2.x10)
.testTag(TransactionHistoryItemTestTags.STATUS_PREFIX + state.status.testTagSuffix),
)
TitleText(
title = state.title,
status = state.status,
modifier = Modifier
.layoutId(TangemRowLayoutId.START_TOP)
.testTag(TransactionHistoryItemTestTags.TITLE),
)
SubtitleText(
subtitle = state.subtitle,
status = state.status,
modifier = Modifier
.layoutId(TangemRowLayoutId.START_BOTTOM)
.padding(top = TangemTheme.dimens2.x0_5),
)
state.amount?.let { amount ->
AmountText(
amount = amount,
status = state.status,
isBalanceHidden = isBalanceHidden,
modifier = Modifier
.layoutId(TangemRowLayoutId.END_TOP)
.testTag(TransactionHistoryItemTestTags.AMOUNT),
)
}
CurrencyText(
symbol = state.currencySymbol,
modifier = Modifier
.layoutId(TangemRowLayoutId.END_BOTTOM)
.padding(top = TangemTheme.dimens2.x0_5)
.testTag(TransactionHistoryItemTestTags.CURRENCY),
)
}
state.warning?.let { warning ->
WarningLine(
warning = warning,
modifier = Modifier.padding(
start = TangemTheme.dimens2.x4,
end = TangemTheme.dimens2.x4,
bottom = TangemTheme.dimens2.x3,
),
)
}
}
}
@Composable
private fun WarningLine(warning: TextReference, modifier: Modifier = Modifier) {
val attention = TangemTheme.colors2.text.status.attention
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
) {
Icon(
painter = painterResource(R.drawable.ic_alert_triangle_20),
contentDescription = null,
tint = attention,
modifier = Modifier.size(TangemTheme.dimens2.x5),
)
TitleText(
title = state.title,
status = state.status,
modifier = Modifier
.layoutId(TangemRowLayoutId.START_TOP)
.testTag(TransactionHistoryItemTestTags.TITLE),
)
SubtitleText(
subtitle = state.subtitle,
status = state.status,
modifier = Modifier
.layoutId(TangemRowLayoutId.START_BOTTOM)
.padding(top = TangemTheme.dimens2.x0_5),
)
AmountText(
amount = state.amount,
status = state.status,
isBalanceHidden = isBalanceHidden,
modifier = Modifier
.layoutId(TangemRowLayoutId.END_TOP)
.testTag(TransactionHistoryItemTestTags.AMOUNT),
)
CurrencyText(
symbol = state.currencySymbol,
modifier = Modifier
.layoutId(TangemRowLayoutId.END_BOTTOM)
.padding(top = TangemTheme.dimens2.x0_5)
.testTag(TransactionHistoryItemTestTags.CURRENCY),
Text(
text = warning.resolveReference(),
color = attention,
style = TangemTheme.typography2.captionMedium12,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
)
}
}
@ -126,7 +174,7 @@ private fun ContentItem(state: TransactionItemUM.Content, isBalanceHidden: Boole
// region Status circle
@Composable
private fun StatusCircle(iconRes: Int, status: Status, modifier: Modifier = Modifier) {
private fun StatusCircle(icon: TxIcon, status: Status, modifier: Modifier = Modifier) {
Box(
modifier = modifier.background(
color = status.backgroundColor,
@ -134,7 +182,7 @@ private fun StatusCircle(iconRes: Int, status: Status, modifier: Modifier = Modi
),
) {
Icon(
painter = painterResource(iconRes),
imageVector = icon.asImageVector(),
contentDescription = null,
tint = status.iconTint,
modifier = Modifier
@ -262,6 +310,21 @@ private fun SubtitleText(subtitle: ContentSubtitle, status: Status, modifier: Mo
modifier = Modifier.fillMaxSize(),
)
}
is ContentSubtitle.Asset -> InlineImageSubtitle(
template = stringResourceSafe(subtitle.direction.templateResId(), subtitle.symbol),
color = tertiary,
afterIconColor = if (isFailed) tertiary else primary,
modifier = modifier,
) {
subtitle.icon?.let { iconState ->
CurrencyIcon(
state = iconState,
shouldDisplayNetwork = false,
withFixedSize = false,
modifier = Modifier.fillMaxSize(),
)
}
}
}
}
@ -341,7 +404,7 @@ private fun String.stripLeadingSign(): String = when {
@Suppress("LongParameterList")
private fun previewContent(
txHash: String,
iconRes: Int,
icon: TxIcon,
direction: Direction,
status: Status,
title: String,
@ -356,7 +419,7 @@ private fun previewContent(
status = status,
direction = direction,
onClick = {},
iconRes = iconRes,
icon = icon,
title = stringReference(title),
subtitle = ContentSubtitle.Plain(stringReference(subtitle)),
timestamp = 0L,
@ -383,7 +446,7 @@ private fun Preview_TransactionItem_Receive() {
items = listOf(
previewContent(
txHash = "rcv-c",
iconRes = R.drawable.ic_arrow_down_24,
icon = TxIcon.Vector(Icons.ic_arrow_down_20),
direction = Direction.INCOMING,
status = Status.Confirmed,
title = "Received",
@ -392,7 +455,7 @@ private fun Preview_TransactionItem_Receive() {
),
previewContent(
txHash = "rcv-u",
iconRes = R.drawable.ic_arrow_down_24,
icon = TxIcon.Vector(Icons.ic_arrow_down_20),
direction = Direction.INCOMING,
status = Status.Unconfirmed,
title = "Receiving",
@ -401,7 +464,7 @@ private fun Preview_TransactionItem_Receive() {
),
previewContent(
txHash = "rcv-f",
iconRes = R.drawable.ic_close_24,
icon = TxIcon.Vector(Icons.ic_cross_20),
direction = Direction.INCOMING,
status = Status.Failed,
title = "Receiving failed",
@ -422,7 +485,7 @@ private fun Preview_TransactionItem_Send() {
items = listOf(
previewContent(
txHash = "snd-c",
iconRes = R.drawable.ic_arrow_up_24,
icon = TxIcon.Vector(Icons.ic_arrow_up_20),
direction = Direction.OUTGOING,
status = Status.Confirmed,
title = "Sent",
@ -431,7 +494,7 @@ private fun Preview_TransactionItem_Send() {
),
previewContent(
txHash = "snd-u",
iconRes = R.drawable.ic_arrow_up_24,
icon = TxIcon.Vector(Icons.ic_arrow_up_20),
direction = Direction.OUTGOING,
status = Status.Unconfirmed,
title = "Sending",
@ -440,7 +503,7 @@ private fun Preview_TransactionItem_Send() {
),
previewContent(
txHash = "snd-f",
iconRes = R.drawable.ic_close_24,
icon = TxIcon.Vector(Icons.ic_cross_20),
direction = Direction.OUTGOING,
status = Status.Failed,
title = "Sending failed",
@ -461,7 +524,7 @@ private fun Preview_TransactionItem_Swap() {
items = listOf(
previewContent(
txHash = "swp-c",
iconRes = R.drawable.ic_exchange_vertical_24,
icon = TxIcon.Vector(Icons.ic_arrow_swap_horizontal_20),
direction = Direction.INCOMING,
status = Status.Confirmed,
title = "Swapped",
@ -470,7 +533,7 @@ private fun Preview_TransactionItem_Swap() {
),
previewContent(
txHash = "swp-u",
iconRes = R.drawable.ic_exchange_vertical_24,
icon = TxIcon.Vector(Icons.ic_arrow_swap_horizontal_20),
direction = Direction.INCOMING,
status = Status.Unconfirmed,
title = "Swapping",
@ -479,7 +542,7 @@ private fun Preview_TransactionItem_Swap() {
),
previewContent(
txHash = "swp-f",
iconRes = R.drawable.ic_close_24,
icon = TxIcon.Vector(Icons.ic_cross_20),
direction = Direction.INCOMING,
status = Status.Failed,
title = "Swapping failed",
@ -491,4 +554,73 @@ private fun Preview_TransactionItem_Swap() {
}
}
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun Preview_TransactionItem_Express() {
TangemThemePreviewRedesign {
PreviewColumn(
items = listOf(
TransactionItemUM.Content(
txHash = "exp-swap-u",
amount = "-390.00",
currencySymbol = "USDT",
time = "",
status = Status.Unconfirmed,
direction = Direction.OUTGOING,
onClick = {},
icon = TxIcon.Vector(Icons.ic_arrow_swap_horizontal_20),
title = stringReference("Swapping"),
subtitle = ContentSubtitle.Asset(
direction = ContentSubtitle.Direction.TO,
symbol = "POL",
icon = CurrencyIconState.CoinIcon(
url = null,
fallbackResId = R.drawable.ic_custom_token_44,
isGrayscale = false,
shouldShowCustomBadge = false,
),
),
timestamp = 0L,
warning = stringReference("KYC verification required by provider"),
),
TransactionItemUM.Content(
txHash = "exp-onramp-c",
amount = "+0.006339",
currencySymbol = "BTC",
time = "",
status = Status.Confirmed,
direction = Direction.INCOMING,
onClick = {},
icon = TxIcon.Vector(Icons.ic_card_20),
title = stringReference("Topped up"),
subtitle = ContentSubtitle.Asset(
direction = ContentSubtitle.Direction.FROM,
symbol = "SEK",
icon = null,
),
timestamp = 0L,
),
TransactionItemUM.Content(
txHash = "exp-onramp-f",
amount = "0.006339",
currencySymbol = "BTC",
time = "",
status = Status.Failed,
direction = Direction.INCOMING,
onClick = {},
icon = TxIcon.Vector(Icons.ic_card_20),
title = stringReference("Top up failed"),
subtitle = ContentSubtitle.Asset(
direction = ContentSubtitle.Direction.FROM,
symbol = "SEK",
icon = null,
),
timestamp = 0L,
),
),
)
}
}
// endregion

View file

@ -21,9 +21,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.R
import com.tangem.core.ui.test.TransactionHistoryItemTestTags
import com.tangem.core.ui.components.icons.identicon.IdentIcon
import com.tangem.core.ui.components.transactions.state.TransactionItemUM
import com.tangem.core.ui.components.transactions.state.TransactionItemUM.Content.Status
@ -45,6 +47,7 @@ internal fun TransactionStatusPill(
Row(
modifier = modifier
.fillMaxWidth()
.testTag(TransactionHistoryItemTestTags.ITEM)
.clickable(onClick = state.onClick)
.padding(horizontal = TangemTheme.dimens2.x4, vertical = TangemTheme.dimens2.x2),
horizontalArrangement = Arrangement.Center,

View file

@ -1,8 +1,12 @@
package com.tangem.core.ui.components.transactions.state
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.ds.image.DeviceIconUM
import com.tangem.core.ui.extensions.TextReference
@ -22,21 +26,23 @@ sealed interface TransactionItemUM {
/**
* Content state.
*
* @property amount signed numeric value, e.g. "+0.500913" / "-350.31"; no currency symbol embedded
* @property amount signed numeric value, e.g. "+0.500913" / "-350.31"; no currency symbol embedded.
* `null` hides the numeric value while [currencySymbol] still shows.
* @property currencySymbol currency symbol shown alongside [amount], e.g. "BTC", "USDT"
*/
data class Content(
override val txHash: String,
val amount: String,
val amount: String?,
val currencySymbol: String,
val time: String,
val status: Status,
val direction: Direction,
val onClick: () -> Unit,
@DrawableRes val iconRes: Int,
val icon: TxIcon,
val title: TextReference,
val subtitle: ContentSubtitle,
val timestamp: Long,
val warning: TextReference? = null,
) : TransactionItemUM {
@Immutable
@ -95,6 +101,19 @@ sealed interface TransactionItemUM {
val deviceIconUM: DeviceIconUM,
) : ContentSubtitle
/**
* Counterparty asset ticker renders as "to/from: <icon> <SYMBOL>". Used for express rows
* (swap counterparty currency / onramp fiat), e.g. "to: ◎ POL" or "from: 🇸🇪 SEK".
*
* @property icon resolved counterparty currency icon, rendered via `CurrencyIcon`. `null` when no icon
* is available (e.g. onramp fiat carries no `CryptoCurrency`) the ticker then renders without a leading icon.
*/
data class Asset(
val direction: Direction,
val symbol: String,
val icon: CurrencyIconState?,
) : ContentSubtitle
enum class Direction { TO, FROM }
}
@ -137,4 +156,40 @@ sealed interface TransactionItemUM {
data class Loading(override val txHash: String) : TransactionItemUM
data class Locked(override val txHash: String) : TransactionItemUM
}
/**
* Status-circle icon for a [TransactionItemUM.Content] row.
*
* [Vector] holds a design-system [ImageVector] (`Icons.ic_*`) the migration target; [Res] holds a `@DrawableRes`
* XML fallback for transaction types that don't have a DS3 icon yet (e.g. gear / claim rewards).
*/
@Immutable
sealed interface TxIcon {
/** Design-system vector icon (`Icons.ic_*`). */
data class Vector(val imageVector: ImageVector) : TxIcon
/**
* Legacy XML drawable fallback.
*
* Forced temporary bridge: a few transaction types still map to legacy XML drawables that have no DS3
* `Icons.ic_*` counterpart yet (e.g. gear / claim rewards), while some DS3 icons in turn have no legacy
* drawable. Once the DS team ships the full icon set, every call site switches to [Vector] and this whole
* subclass is removed.
*/
@Deprecated(
message = "Temporary fallback for tx types missing a DS3 icon. Migrate to TxIcon.Vector once the DS team " +
"ships the remaining Icons.ic_* glyphs; this subclass will then be removed.",
replaceWith = ReplaceWith("TxIcon.Vector(imageVector)"),
)
data class Res(@DrawableRes val resId: Int) : TxIcon
}
/** Resolves a [TxIcon] to the [ImageVector] to draw: the DS3 vector directly, or the legacy XML drawable parsed. */
@Suppress("DEPRECATION")
@Composable
fun TxIcon.asImageVector(): ImageVector = when (this) {
is TxIcon.Vector -> imageVector
is TxIcon.Res -> ImageVector.vectorResource(resId)
}

View file

@ -97,9 +97,11 @@ fun TangemPagerIndicator(
contentAlignment = Alignment.Center,
) {
Row(
modifier = Modifier.offset {
IntOffset(animState.slideOffset.value.roundToInt(), 0)
},
modifier = Modifier
.wrapContentWidth(unbounded = true)
.offset {
IntOffset(animState.slideOffset.value.roundToInt(), 0)
},
horizontalArrangement = Arrangement.spacedBy(SPACING),
verticalAlignment = Alignment.CenterVertically,
) {
@ -367,8 +369,8 @@ val TangemPagerIndicatorColors: PagerIndicatorColors
@Composable
@ReadOnlyComposable
get() = PagerIndicatorColors(
active = TangemTheme.colors2.graphic.neutral.primary,
inactive = TangemTheme.colors2.graphic.neutral.tertiary,
active = TangemTheme.colors3.bg.inverse,
inactive = TangemTheme.colors3.bg.opaque.secondary,
overlay = null,
)
@ -413,6 +415,7 @@ private class TangemPagerIndicatorPreviewProvider : PreviewParameterProvider<Int
1,
2,
3,
4,
5,
6,
7,

View file

@ -23,11 +23,10 @@ import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.constrainHeight
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
import com.tangem.core.ui.ds.button.SecondaryTangemButton
import com.tangem.core.ui.ds.button.TangemButtonShape
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.ds2.button.TangemButton
import com.tangem.core.ui.extensions.orEmpty
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringReference
@ -109,12 +108,12 @@ private fun ActionButton(button: TangemButtonUM, modifier: Modifier = Modifier)
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
horizontalAlignment = Alignment.CenterHorizontally,
) {
SecondaryTangemButton(
tangemIconUM = button.tangemIconUM,
TangemButton(
onClick = button.onClick,
variant = TangemButton.Variant.Material,
isEnabled = button.isEnabled,
shape = TangemButtonShape.Rounded,
onLongClick = button.onLongClick,
iconStart = button.tangemIconUM,
size = TangemButton.Size.X14,
)
Text(
text = button.text.orEmpty().resolveReference(),

View file

@ -22,6 +22,7 @@ import com.tangem.core.ui.res.TangemTheme
fun RowScope.TokenRowPriceChangeContent(
priceChangeState: PriceChangeState.Content,
isFlickering: Boolean,
modifier: Modifier = Modifier,
isAvailable: Boolean = true,
) {
val color = when (priceChangeState.type) {
@ -54,7 +55,7 @@ fun RowScope.TokenRowPriceChangeContent(
AnimatedContent(
targetState = priceChangeState.valueInPercent,
label = "Update the price text",
modifier = Modifier.padding(start = TangemTheme.dimens2.x0_5),
modifier = modifier.padding(start = TangemTheme.dimens2.x0_5),
) { animatedText ->
Text(
text = animatedText,

View file

@ -3,17 +3,19 @@ package com.tangem.core.ui.ds2.button
import androidx.compose.runtime.Composable
import androidx.compose.runtime.NonRestartableComposable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.graphics.vector.ImageVector
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.res.generated.icons.Icons
import com.tangem.core.ui.res.generated.icons.ic_chevron_left_20
import com.tangem.core.ui.res.generated.icons.ic_cross_20
import com.tangem.core.ui.test.TopNavigationTestTags
@Composable
@NonRestartableComposable
fun TangemButton.Back(modifier: Modifier = Modifier, onClick: () -> Unit) {
TangemButton(
modifier = modifier,
modifier = modifier.testTag(TopNavigationTestTags.BACK_BUTTON),
variant = TangemButton.Variant.Material,
size = TangemButton.Size.X11,
iconStart = TangemIconUM.Icon(Icons.ic_chevron_left_20),

View file

@ -3,14 +3,7 @@
package com.tangem.core.ui.ds2.messagebanner
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
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.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ripple.RippleAlpha
import androidx.compose.material3.Icon
@ -33,6 +26,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.ds.image.TangemIcon
import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.ds2.button.TangemButton
import com.tangem.core.ui.ds2.glowring.TangemGlowRing
@ -165,6 +159,49 @@ fun TangemMessageBanner(
}
}
/**
* Design-system v2 (DS3) **Message Banner** title/description header with optional slots and an
* action-button row.
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=5475-7680&m=dev)
*
* @param state component state model
* @param modifier component Modifier
* @param extraBottomSlot Slot under the description, inside the text column.
*/
@Suppress("LongParameterList")
@Composable
fun TangemMessageBanner(
state: TangemMessageBanner.State,
modifier: Modifier = Modifier,
extraBottomSlot: (@Composable ColumnScope.() -> Unit)? = null,
) {
TangemMessageBanner(
modifier = modifier,
variant = state.variant,
showGlowRing = state.shouldShowGlowRing,
secondaryButton = state.secondaryButton,
primaryButton = state.primaryButton,
) {
MessageBannerContentRow(
title = state.title,
description = state.description,
contentAlign = state.contentAlign,
slotStart = if (state.iconStart != null) {
{ TangemIcon(state.iconStart) }
} else {
null
},
slotEnd = if (state.iconEnd != null) {
{ TangemIcon(state.iconEnd) }
} else {
null
},
extraBottomSlot = extraBottomSlot,
)
}
}
@Suppress("LongParameterList")
@Composable
private fun MessageBannerContentRow(
@ -190,7 +227,11 @@ private fun MessageBannerContentRow(
horizontalArrangement = Arrangement.spacedBy(12.dp),
) {
slotStart?.let { slot -> Box(modifier = Modifier.align(Alignment.Top)) { slot() } }
textWrapper(Modifier.weight(1f).align(Alignment.Top))
textWrapper(
Modifier
.weight(1f)
.align(Alignment.Top),
)
slotEnd?.let { slot -> Box(modifier = Modifier.align(Alignment.Top)) { slot() } }
}
TangemMessageBanner.ContentAlign.Center -> Box(modifier = Modifier.fillMaxWidth()) {
@ -315,6 +356,32 @@ object TangemMessageBanner {
val isEnabled: Boolean = true,
val isLoading: Boolean = false,
)
/**
* A model holding configuration data for TangemMessageBanner
*
* @param title Banner headline.
* @param variant Visual appearance background color + glow ring.
* @param contentAlign Horizontal alignment of the text block.
* @param shouldShowGlowRing Whether the glow ring is drawn around the banner. `false` shows only the
* background.
* @param description Secondary line under the [title]. `null` hides it.
* @param secondaryButton Start action. `null` hides it.
* @param primaryButton End action. `null` hides it.
* @param iconStart Leading icon before the title. `null` hides it.
* @param iconEnd Trailing icon after the title (e.g. the [CloseButton] preset). `null` hides it.
*/
data class State(
val title: TextReference,
val variant: Variant = Variant.Default,
val contentAlign: ContentAlign = ContentAlign.Start,
val shouldShowGlowRing: Boolean = true,
val description: TextReference? = null,
val secondaryButton: Button? = null,
val primaryButton: Button? = null,
val iconStart: TangemIconUM? = null,
val iconEnd: TangemIconUM? = null,
)
}
/**

View file

@ -0,0 +1,280 @@
@file:Suppress("MagicNumber")
package com.tangem.core.ui.ds2.messagebubble
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.RoundRect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Outline
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.PathOperation
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.clickableSingle
import com.tangem.core.ui.extensions.conditionalCompose
import com.tangem.core.ui.extensions.resolveAnnotatedReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.res.generated.icons.Icons
import com.tangem.core.ui.res.generated.icons.ic_cross_circle_16_filled
import com.tangem.core.ui.res.generated.icons.ic_info_16
/**
* Design-system v2 (DS3) **Message Bubble** a compact caption pill with an optional leading icon,
* an optional close button and an optional "tip" tail on top pointing at the anchored element.
* DS3 replacement for the legacy `TokenRowPromoBanner`.
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=6327-22326)
*
* @param text Bubble message, rendered in caption/medium typography.
* @param modifier Modifier applied to the bubble. The bubble hugs its content in both dimensions.
* @param variant Visual appearance background, text and tip colors.
* @param showTip Whether the tail on top of the bubble is drawn. `false` shows only the pill.
* @param icon Leading 16dp icon, tinted with the [variant] content color. `null` hides it.
* @param onClick Invoked when the bubble body is tapped. `null` makes the bubble non-interactive.
* @param onClose Invoked when the close button is tapped. `null` hides the button.
* @param closeContentDescription Accessibility label for the close button announced by TalkBack
* (e.g. `"Dismiss"`). Supply it whenever [onClose] is set.
*/
@Suppress("LongParameterList")
@Composable
fun TangemMessageBubble(
text: TextReference,
modifier: Modifier = Modifier,
variant: TangemMessageBubble.Variant = TangemMessageBubble.Variant.Neutral,
showTip: Boolean = true,
icon: ImageVector? = null,
onClick: (() -> Unit)? = null,
onClose: (() -> Unit)? = null,
closeContentDescription: String? = null,
) {
val tokens = variant.tokens()
val shape = if (showTip) MessageBubbleShape else RoundedCornerShape(12.dp)
Row(
modifier = modifier
.clip(shape)
.background(tokens.background)
.conditionalCompose(onClick != null) {
clickableSingle(role = Role.Button, onClick = requireNotNull(onClick))
}
.padding(
start = 8.dp,
top = if (showTip) 12.dp else 4.dp,
end = if (onClose != null) 4.dp else 8.dp,
bottom = 4.dp,
),
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalAlignment = Alignment.CenterVertically,
) {
if (icon != null) {
Icon(
imageVector = icon,
contentDescription = null,
tint = tokens.content,
modifier = Modifier.size(16.dp),
)
}
Text(
text = text.resolveAnnotatedReference(),
style = TangemTheme.typography3.caption.medium,
color = tokens.content,
)
if (onClose != null) {
CloseButton(
onClick = onClose,
tint = tokens.closeIcon,
contentDescription = closeContentDescription,
)
}
}
}
/** Public API surface of [TangemMessageBubble]. */
object TangemMessageBubble {
/** Visual appearance — background, text and tip colors. */
enum class Variant {
/** Neutral tertiary background with secondary text. */
Neutral,
/** Subtle success-green background with success text. */
Success,
/** Subtle info-blue background with info text. */
Info,
}
}
@Composable
private fun CloseButton(onClick: () -> Unit, tint: Color, contentDescription: String?, modifier: Modifier = Modifier) {
Box(
modifier = modifier
.padding(start = 4.dp)
.size(16.dp),
contentAlignment = Alignment.Center,
) {
Box(
modifier = Modifier
.requiredSize(28.dp)
.clip(RoundedCornerShape(percent = 50))
.clickableSingle(onClick = onClick)
.semantics {
role = Role.Button
contentDescription?.let { this.contentDescription = it }
},
contentAlignment = Alignment.Center,
) {
Icon(
imageVector = Icons.ic_cross_circle_16_filled,
contentDescription = null,
tint = tint,
modifier = Modifier.size(16.dp),
)
}
}
}
/**
* Pill with the tip tail as a single-path [Shape]: an 8x8 swoosh (apex at the top-start corner,
* concave curve down to the bottom-end the geometry of the legacy `shape_triangular` drawable)
* sitting on a 12dp-rounded rect. One shape means no anti-aliasing seam between tail and pill, no
* double-painting of translucent background tokens, and a ripple clipped to the full silhouette.
*/
private object MessageBubbleShape : Shape {
override fun createOutline(size: Size, layoutDirection: LayoutDirection, density: Density): Outline {
val path = Path.combine(
operation = PathOperation.Union,
path1 = density.pillPath(size),
path2 = density.tipPath(size, layoutDirection),
)
return Outline.Generic(path)
}
private fun Density.pillPath(size: Size): Path = Path().apply {
addRoundRect(
RoundRect(
left = 0f,
top = 8.dp.toPx(),
right = size.width,
bottom = size.height,
cornerRadius = CornerRadius(12.dp.toPx()),
),
)
}
private fun Density.tipPath(size: Size, layoutDirection: LayoutDirection): Path {
val tipWidth = 8.dp.toPx()
val tipHeight = 8.dp.toPx()
// Extends below the tip band, into the pill, to guarantee the union shapes overlap.
val skirtHeight = 2.dp.toPx()
val startX = when (layoutDirection) {
LayoutDirection.Ltr -> 16.dp.toPx()
LayoutDirection.Rtl -> size.width - 16.dp.toPx() - tipWidth
}
// Maps a 0..1 fraction of the tip width to an x coordinate, mirrored in RTL.
fun x(fraction: Float): Float = when (layoutDirection) {
LayoutDirection.Ltr -> startX + fraction * tipWidth
LayoutDirection.Rtl -> startX + (1 - fraction) * tipWidth
}
// Vector drawable path "M8,8 L0,8 L0,0 C0,0 2,6 8,8 Z" in an 8x8 viewport.
return Path().apply {
moveTo(x(1f), tipHeight + skirtHeight)
lineTo(x(0f), tipHeight + skirtHeight)
lineTo(x(0f), 0f)
cubicTo(
x1 = x(0f),
y1 = 0f,
x2 = x(0.25f),
y2 = tipHeight * 0.75f,
x3 = x(1f),
y3 = tipHeight,
)
close()
}
}
}
/** Resolved appearance tokens for a [TangemMessageBubble.Variant]. */
private data class MessageBubbleTokens(val background: Color, val content: Color, val closeIcon: Color)
@Composable
@ReadOnlyComposable
private fun TangemMessageBubble.Variant.tokens(): MessageBubbleTokens {
val colors = TangemTheme.colors3
return when (this) {
TangemMessageBubble.Variant.Neutral -> MessageBubbleTokens(
background = colors.bg.tertiary,
content = colors.text.secondary,
closeIcon = colors.icon.secondary,
)
TangemMessageBubble.Variant.Success -> MessageBubbleTokens(
background = colors.bg.status.successSubtle,
content = colors.text.status.success,
closeIcon = colors.icon.status.success,
)
TangemMessageBubble.Variant.Info -> MessageBubbleTokens(
background = colors.bg.status.infoSubtle,
content = colors.text.status.info,
closeIcon = colors.icon.status.info,
)
}
}
@Preview(name = "Light", showBackground = true)
@Preview(name = "Dark", uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES, showBackground = true)
@Composable
private fun TangemMessageBubblePreview() {
TangemThemePreviewRedesign {
Column(
modifier = Modifier
.background(TangemTheme.colors3.bg.primary)
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
TangemMessageBubble.Variant.entries.forEach { variant ->
TangemMessageBubble(
text = stringReference("Description"),
variant = variant,
icon = Icons.ic_info_16,
onClick = {},
onClose = {},
closeContentDescription = "Dismiss",
)
}
TangemMessageBubble(
text = stringReference("Text only"),
showTip = false,
)
TangemMessageBubble(
text = stringReference("No icon"),
variant = TangemMessageBubble.Variant.Info,
onClose = {},
closeContentDescription = "Dismiss",
)
}
}
}

View file

@ -19,6 +19,7 @@ import androidx.compose.ui.graphics.LinearGradientShader
import androidx.compose.ui.graphics.Shader
import androidx.compose.ui.graphics.ShaderBrush
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.haze.hazeEffectTangem
@ -70,6 +71,7 @@ fun TangemSurface(
onClick: (() -> Unit)? = null,
enabled: Boolean = true,
interactionSource: MutableInteractionSource? = null,
shadowRadius: Dp = 40.dp,
content: @Composable () -> Unit,
) {
val resolvedInteractionSource = interactionSource ?: remember { MutableInteractionSource() }
@ -77,7 +79,7 @@ fun TangemSurface(
val surface: @Composable () -> Unit = {
Box(
modifier = modifier
.conditionalCompose(isMaterial) { materialShadow(shape) }
.conditionalCompose(isMaterial) { materialShadow(shape, shadowRadius) }
.conditionalCompose(border != null) { border(border!!, shape) }
.conditionalCompose(isMaterial) { materialBorder(shape) }
.clip(shape)
@ -115,10 +117,10 @@ fun TangemSurface(
* `isAlphaContentClip`) to avoid the dark blur bleeding through the surface.
*/
@Composable
private fun Modifier.materialShadow(shape: Shape): Modifier {
private fun Modifier.materialShadow(shape: Shape, radius: Dp): Modifier {
val isBlurEnabled = LocalHazeState.current.blurEnabled
return softLayerShadow(
radius = 40.dp,
radius = radius,
color = Color.Black.copy(alpha = 0.12f),
shape = shape,
spread = 0.dp,

View file

@ -0,0 +1,427 @@
package com.tangem.core.ui.ds2.tokenicon
import android.util.LruCache
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImagePainter
import coil.compose.rememberAsyncImagePainter
import coil.request.ImageRequest
import com.tangem.core.ui.R
import com.tangem.core.ui.ds2.shimmers.TangemShimmer
import com.tangem.core.ui.ds2.tokenicon.TangemTokenIcon.State.Indicator
import com.tangem.core.ui.extensions.ColorReference2
import com.tangem.core.ui.extensions.conditionalCompose
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.core.ui.res.generated.assets.il_token_custom
import com.tangem.core.ui.res.generated.assets.il_token_error
import com.tangem.core.ui.res.generated.icons.Icons
import com.tangem.core.ui.utils.ImageBackgroundContrastChecker
import com.tangem.core.ui.utils.getGreyScaleColorFilter
import kotlinx.coroutines.launch
/**
* Design-system v2 token icon rendered from a high-level [TangemTokenIcon.UiState] a loaded token,
* a loading shimmer, or an error placeholder.
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=3901-470)
*
* @param state High-level rendering state; see [TangemTokenIcon.UiState].
* @param size One of the fixed [TangemTokenIcon.Size] presets driving the icon and overlay dimensions.
* @param modifier Modifier applied to the icon root. The icon is fixed-size per [size]; use this to
* position it within the parent.
* @param contentDescription Accessibility label describing the token this icon represents.
*/
@Composable
fun TangemTokenIcon(
state: TangemTokenIcon.UiState,
size: TangemTokenIcon.Size,
modifier: Modifier = Modifier,
contentDescription: String? = null,
) {
when (state) {
TangemTokenIcon.UiState.Error -> {
Image(
modifier = modifier.size(size.tokens().size),
imageVector = Icons.il_token_error,
contentDescription = contentDescription,
)
}
is TangemTokenIcon.UiState.Token -> {
TangemTokenIcon(
state = state.tokenState,
size = size,
modifier = modifier,
contentDescription = contentDescription,
)
}
TangemTokenIcon.UiState.Shimmer -> {
TangemShimmer(radius = 999.dp, modifier = modifier.size(size.tokens().size))
}
}
}
/**
* Design-system v2 token icon rendered from a fully-resolved [TangemTokenIcon.State].
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=3901-470)
*
* @param state Resolved icon state; see [TangemTokenIcon.State].
* @param size One of the fixed [TangemTokenIcon.Size] presets driving the icon and overlay dimensions.
* @param modifier Modifier applied to the icon root. The icon is fixed-size per [size]; use this to
* position it within the parent.
* @param contentDescription Accessibility label describing the token
*/
@Suppress("LongMethod")
@Composable
fun TangemTokenIcon(
state: TangemTokenIcon.State,
size: TangemTokenIcon.Size,
modifier: Modifier = Modifier,
contentDescription: String? = null,
) {
val (alpha, colorFilter) = remember(state.isGrayscale) {
getGreyScaleColorFilter(state.isGrayscale)
}
val itemBackgroundColor = TangemTheme.colors.background.primary.toArgb()
val isDarkTheme = isSystemInDarkTheme()
val coroutineScope = rememberCoroutineScope()
val sizeTokens = size.tokens()
val pixelsSize = with(LocalDensity.current) { sizeTokens.size.roundToPx() }
val context = LocalContext.current
val iconUrl = state.url?.takeIf(String::isNotBlank)
val iconData: Any = iconUrl.orEmpty()
var iconBackgroundColor by remember(iconData) {
mutableStateOf(iconUrl?.let(contrastColorCache::get) ?: Color.Transparent)
}
var isBackgroundColorDefined by remember(iconData) {
mutableStateOf(iconUrl != null && contrastColorCache.get(iconUrl) != null)
}
val imageRequest = remember(iconData, pixelsSize, isDarkTheme, itemBackgroundColor) {
ImageRequest.Builder(context = context)
.data(iconData)
.size(size = pixelsSize)
.memoryCacheKey(key = iconData.toString() + pixelsSize)
.crossfade(enable = true)
.allowHardware(enable = !isDarkTheme) // Hardware bitmaps can't be read for Palette quantization.
.listener(
onSuccess = { _, result ->
if (!isBackgroundColorDefined && isDarkTheme && iconUrl != null) {
coroutineScope.launch {
val color = ImageBackgroundContrastChecker(
drawable = result.drawable,
backgroundColor = itemBackgroundColor,
size = pixelsSize,
).getContrastColor(isDarkTheme = true)
contrastColorCache.put(iconUrl, color)
iconBackgroundColor = color
isBackgroundColorDefined = true
}
}
},
).build()
}
Box(
modifier = modifier.size(sizeTokens.size),
) {
val hasCutout = state.topIcon != null || state.indicator != null
val baseModifier = Modifier
.matchParentSize()
.conditionalCompose(hasCutout) {
graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen }
.drawWithContent {
val drawSize = this.size
drawContent()
if (state.topIcon != null) {
drawCircle(
color = Color.Transparent,
radius = (sizeTokens.topIconSize / 2 + CUTOUT).toPx(),
center = Offset(
x = drawSize.width -
(sizeTokens.topIconSize / 2 + sizeTokens.topIconOffset).toPx(),
y = (sizeTokens.topIconOffset + sizeTokens.topIconSize / 2).toPx(),
),
blendMode = BlendMode.Clear,
)
}
if (state.indicator != null) {
val indicatorCenter = drawSize.width -
(sizeTokens.indicatorOffset + sizeTokens.indicatorSize / 2).toPx()
drawCircle(
color = Color.Transparent,
radius = (sizeTokens.indicatorSize / 2 + CUTOUT).toPx(),
center = Offset(x = indicatorCenter, y = indicatorCenter),
blendMode = BlendMode.Clear,
)
}
}
}
.background(
color = iconBackgroundColor,
shape = RoundedCornerShape(8.dp),
)
.clip(RoundedCornerShape(8.dp))
if (state.url == null) {
Image(
modifier = baseModifier,
imageVector = Icons.il_token_custom,
contentDescription = contentDescription,
alpha = alpha,
colorFilter = colorFilter,
)
} else {
TokenAsyncImage(
imageRequest = imageRequest,
alpha = alpha,
colorFilter = colorFilter,
contentDescription = contentDescription,
modifier = baseModifier,
)
}
if (state.topIcon != null) {
Image(
modifier = Modifier
.offset(x = -sizeTokens.topIconOffset, y = sizeTokens.topIconOffset)
.align(Alignment.TopEnd)
.size(size = sizeTokens.topIconSize),
imageVector = state.topIcon,
contentDescription = null,
colorFilter = colorFilter,
alpha = alpha,
)
}
if (state.indicator != null) {
Box(
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(end = sizeTokens.indicatorOffset, bottom = sizeTokens.indicatorOffset)
.size(size = sizeTokens.indicatorSize)
.background(
color = state.indicator.colorReference2(),
shape = CircleShape,
)
.padding(1.dp),
)
}
}
}
@Composable
private fun TokenAsyncImage(
imageRequest: ImageRequest,
alpha: Float,
colorFilter: ColorFilter?,
modifier: Modifier = Modifier,
contentDescription: String? = null,
) {
val painter = rememberAsyncImagePainter(model = imageRequest)
when (painter.state) {
is AsyncImagePainter.State.Success -> {
Image(
modifier = modifier,
painter = painter,
contentDescription = contentDescription,
alpha = alpha,
colorFilter = colorFilter,
)
}
is AsyncImagePainter.State.Error -> {
Image(
modifier = modifier,
imageVector = Icons.il_token_error,
contentDescription = contentDescription,
alpha = alpha,
colorFilter = colorFilter,
)
}
else -> {
TangemShimmer(radius = 999.dp, modifier = modifier)
}
}
}
/** Public API namespace for [TangemTokenIcon]. */
object TangemTokenIcon {
/** High-level rendering state for the [TangemTokenIcon] overload that accepts a [UiState]. */
@Immutable
sealed class UiState {
/** A resolved token icon, described by [tokenState]. */
data class Token(val tokenState: State) : UiState()
/** Loading placeholder — a circular shimmer. */
data object Shimmer : UiState()
/** Failure placeholder — the static error illustration. */
data object Error : UiState()
}
/**
* Fully-resolved token-icon state.
*
* @param url Remote image URL. `null` renders the custom-token illustration; blank is treated as `null`.
* @param topIcon Optional overlay icon drawn at the top-end corner (e.g. a network badge), with a
* transparent cutout punched behind it.
* @param isGrayscale When `true`, the whole icon is desaturated and dimmed.
* @param indicator Optional small status dot drawn at the bottom-end corner, with a cutout behind it.
*/
data class State(
val url: String?,
val topIcon: ImageVector? = null,
val isGrayscale: Boolean = false,
val indicator: Indicator? = null,
) {
/**
* Bottom-end status dot.
*
* @param colorReference2 Fill color of the dot, resolved from DS3 tokens.
*/
data class Indicator(
val colorReference2: ColorReference2 = ColorReference2 { TangemTheme.colors3.icon.tertiary },
)
}
/** Fixed icon size presets, in dp (`X40` = 40.dp … `X72` = 72.dp). */
enum class Size {
X40, X44, X56, X72
}
}
private fun TangemTokenIcon.Size.tokens(): Tokens {
return when (this) {
TangemTokenIcon.Size.X40 -> Tokens(
size = 40.dp,
topIconSize = 12.dp,
topIconOffset = (-1).dp,
indicatorSize = 6.dp,
indicatorOffset = 3.dp,
)
TangemTokenIcon.Size.X44 -> Tokens(
size = 44.dp,
topIconSize = 16.dp,
topIconOffset = (-2).dp,
indicatorSize = 6.dp,
indicatorOffset = 4.dp,
)
TangemTokenIcon.Size.X56 -> Tokens(
size = 56.dp,
topIconSize = 20.dp,
topIconOffset = (-4).dp,
indicatorSize = 6.dp,
indicatorOffset = 5.dp,
)
TangemTokenIcon.Size.X72 -> Tokens(
size = 72.dp,
topIconSize = 24.dp,
topIconOffset = (-4).dp,
indicatorSize = 8.dp,
indicatorOffset = 6.dp,
)
}
}
private class Tokens(
val size: Dp,
val topIconSize: Dp,
val topIconOffset: Dp,
val indicatorSize: Dp,
val indicatorOffset: Dp,
)
/** Transparent gap cut out of the base icon around the top icon and the indicator. */
private val CUTOUT = 1.dp
private const val CONTRAST_COLOR_CACHE_SIZE = 100
/**
* Caches the dark-theme contrast background color per icon URL so that revisiting an icon while
* scrolling reuses the result instead of re-decoding the bitmap and re-running Palette quantization.
*/
private val contrastColorCache = LruCache<String, Color>(CONTRAST_COLOR_CACHE_SIZE)
@Preview(name = "Light", showBackground = true)
@Preview(name = "Dark", uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES, showBackground = true)
@Composable
private fun TangemTokenIconPreview() {
TangemThemePreviewRedesign {
Column(
modifier = Modifier
.background(TangemTheme.colors3.bg.primary)
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
PreviewRow(
state = TangemTokenIcon.State(url = ""),
)
PreviewRow(
state = TangemTokenIcon.State(
url = "",
indicator = Indicator(
colorReference2 = { TangemTheme.colors3.icon.brand },
),
topIcon = ImageVector.vectorResource(R.drawable.img_btc_cash_22),
),
)
PreviewRow(
state = TangemTokenIcon.State(url = null, isGrayscale = true),
)
}
}
}
@Composable
private fun PreviewRow(state: TangemTokenIcon.State, modifier: Modifier = Modifier) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp),
) {
TangemTokenIcon.Size.entries.forEach { size ->
TangemTokenIcon(state = state, size = size)
}
}
}

View file

@ -0,0 +1,719 @@
@file:Suppress("MagicNumber")
package com.tangem.core.ui.ds2.tokenrow
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
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.Immutable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.ds2.badge.TangemBadge
import com.tangem.core.ui.ds2.messagebubble.TangemMessageBubble
import com.tangem.core.ui.ds2.tokenicon.TangemTokenIcon
import com.tangem.core.ui.ds2.util.TangemPriceChange
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.TangemThemePreviewRedesign
import com.tangem.core.ui.res.generated.icons.Icons
import com.tangem.core.ui.res.generated.icons.ic_chart_bar_vertical_16
import com.tangem.core.ui.res.generated.icons.ic_sign_equal_24
/**
* Design-system v2 (DS3) **Token Row** a portfolio list item: token icon, title with an optional
* badge, quote + price change, fiat/crypto balances and an optional message-bubble promo line
* underneath. DS3 replacement for the legacy `ds/row/token` `TangemTokenRow`.
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=5723-2473)
*
* @param icon Token icon state, rendered at 40dp. See [TangemTokenIcon.UiState].
* @param title Token name. Single line, ellipsized.
* @param modifier Modifier applied to the row container.
* @param badge Optional [TangemTokenRow.Badge] after the title (e.g. an `"APY 5.47%"` chip; use a
* [TangemBadge.Variant.Solid] badge for the filled look). `null` hides it.
* @param hasPending Shows a small spinner after the title while a transaction is pending.
* @param quote Fiat quote for one token (e.g. `"$1.00"`). `null` hides it.
* @param priceChange Price change indicator next to the quote. `null` hides it.
* @param fiatBalance Primary balance at the end (e.g. `"$583.00"`). `null` hides the line.
* @param cryptoBalance Secondary balance under [fiatBalance] (e.g. `"0,000015 BTC"`). `null` hides it.
* @param showContractWarning Shows the orange contract-error warning before [fiatBalance].
* @param showUpdateWarning Shows the cloud update-error icon before [fiatBalance].
* @param isBalanceHidden When `true`, [fiatBalance] and [cryptoBalance] are masked with stars.
* @param isQuoteFlickering Runs the blade animation over [quote] and [priceChange] while the price
* is being refreshed.
* @param isBalanceFlickering Runs the blade animation over the balances while they are being
* refreshed.
* @param messageBubble Optional slot below the row content pass a [TangemMessageBubble].
* @param onClick Row click handler. `null` with no [onLongClick] makes the row non-interactive.
* @param onLongClick Row long-press handler. `null` disables long-press.
*/
@Suppress("LongParameterList")
@Composable
fun TangemTokenRow(
icon: TangemTokenIcon.UiState,
title: TextReference,
modifier: Modifier = Modifier,
badge: TangemTokenRow.Badge? = null,
hasPending: Boolean = false,
quote: TextReference? = null,
priceChange: TangemPriceChange.State? = null,
fiatBalance: TextReference? = null,
cryptoBalance: TextReference? = null,
showContractWarning: Boolean = false,
showUpdateWarning: Boolean = false,
isBalanceHidden: Boolean = false,
isQuoteFlickering: Boolean = false,
isBalanceFlickering: Boolean = false,
messageBubble: (@Composable () -> Unit)? = null,
onClick: (() -> Unit)? = null,
onLongClick: (() -> Unit)? = null,
) {
TokenRowContainer(
modifier = modifier,
onClick = onClick,
onLongClick = onLongClick,
) {
TokenRowHeadIcon(icon = icon)
TokenRowTitleContent(
title = title,
badge = badge,
hasPending = hasPending,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.START_TOP)
.padding(end = 8.dp),
)
if (quote != null || priceChange != null) {
TokenRowSubtitleContent(
quote = quote,
priceChange = priceChange,
isFlickering = isQuoteFlickering,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.START_BOTTOM)
.padding(end = 8.dp),
)
}
if (fiatBalance != null) {
TokenRowBalanceContent(
fiatBalance = fiatBalance,
showContractWarning = showContractWarning,
showUpdateWarning = showUpdateWarning,
isFlickering = isBalanceFlickering,
isBalanceHidden = isBalanceHidden,
modifier = Modifier.layoutId(layoutId = TokenRowLayoutId.END_TOP),
)
}
if (cryptoBalance != null) {
TokenRowCaptionText(
text = cryptoBalance,
isFlickering = isBalanceFlickering,
isBalanceHidden = isBalanceHidden,
modifier = Modifier.layoutId(layoutId = TokenRowLayoutId.END_BOTTOM),
)
}
if (messageBubble != null) {
Box(
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.EXTRA_BOTTOM)
.padding(start = 40.dp, bottom = 8.dp)
.fillMaxWidth(),
) {
messageBubble()
}
}
}
}
/** Public API surface of [TangemTokenRow]. */
object TangemTokenRow {
/**
* Badge shown after the title (e.g. an `"APY 5.47%"` chip). Wraps [TangemBadge] so callers can
* pick a tinted or a filled ([TangemBadge.Variant.Solid]) look with a status color, as in
* production usage.
*
* @param text Badge label.
* @param variant Badge appearance [TangemBadge.Variant.Tinted] (default) or
* [TangemBadge.Variant.Solid] for the filled look. See [TangemBadge.Variant].
* @param status Status color scheme. See [TangemBadge.Status].
*/
@Immutable
data class Badge(
val text: TextReference,
val variant: TangemBadge.Variant = TangemBadge.Variant.Tinted,
val status: TangemBadge.Status = TangemBadge.Status.Neutral,
)
/**
* Model of the message bubble rendered under the row content by the [State.Content] overload.
* Mirrors the [TangemMessageBubble] parameters.
*
* @param text Bubble message.
* @param variant Bubble appearance. See [TangemMessageBubble.Variant].
* @param shouldShowTip Whether the tail on top of the bubble is drawn.
* @param icon Leading 16dp bubble icon. `null` hides it.
* @param onClick Invoked when the bubble body is tapped. `null` makes it non-interactive.
* @param onClose Invoked when the bubble close button is tapped. `null` hides the button.
* @param closeContentDescription Accessibility label for the bubble close button.
*/
@Immutable
data class MessageBubble(
val text: TextReference,
val variant: TangemMessageBubble.Variant = TangemMessageBubble.Variant.Neutral,
val shouldShowTip: Boolean = true,
val icon: ImageVector? = null,
val onClick: (() -> Unit)? = null,
val onClose: (() -> Unit)? = null,
val closeContentDescription: String? = null,
)
/**
* State model of [TangemTokenRow] one subtype per Figma variant. Render it with the
* `TangemTokenRow(state = )` overload.
*/
@Immutable
sealed class State {
/** Unique id, e.g. for `LazyColumn` item keys. */
abstract val id: String
/**
* Default variant balances, optional badge and an optional message bubble.
*
* @param id Unique id.
* @param icon Token icon state.
* @param title Token name.
* @param badge Badge after the title. `null` hides it. See [Badge].
* @param hasPending Shows a small spinner after the title while a transaction is pending.
* @param quote Fiat quote for one token. `null` hides it.
* @param priceChange Price change indicator next to the quote. `null` hides it.
* @param fiatBalance Primary balance at the end. `null` hides the line.
* @param cryptoBalance Secondary balance under [fiatBalance]. `null` hides it.
* @param shouldShowContractWarning Shows the contract-error warning before [fiatBalance].
* @param shouldShowUpdateWarning Shows the update-error icon before [fiatBalance].
* @param isQuoteFlickering Runs the blade animation over the quote and price change while
* the price is being refreshed.
* @param isBalanceFlickering Runs the blade animation over the balances while they are
* being refreshed.
* @param messageBubble Message bubble under the row content. `null` hides it.
* @param onClick Row click handler. `null` with no [onLongClick] makes the row
* non-interactive.
* @param onLongClick Row long-press handler. `null` disables long-press.
*/
data class Content(
override val id: String,
val icon: TangemTokenIcon.UiState,
val title: TextReference,
val badge: Badge? = null,
val hasPending: Boolean = false,
val quote: TextReference? = null,
val priceChange: TangemPriceChange.State? = null,
val fiatBalance: TextReference? = null,
val cryptoBalance: TextReference? = null,
val shouldShowContractWarning: Boolean = false,
val shouldShowUpdateWarning: Boolean = false,
val isQuoteFlickering: Boolean = false,
val isBalanceFlickering: Boolean = false,
val messageBubble: MessageBubble? = null,
val onClick: (() -> Unit)? = null,
val onLongClick: (() -> Unit)? = null,
) : State()
/**
* Organize (reorder) variant ticker after the title, fiat balance underneath, drag
* handle at the end. Pass the reorder modifier via `dragHandleModifier` of the overload.
*
* @param id Unique id.
* @param icon Token icon state.
* @param title Token name.
* @param ticker Currency ticker after the title. `null` hides it.
* @param fiatBalance Balance line under the title. `null` hides it.
*/
data class Organize(
override val id: String,
val icon: TangemTokenIcon.UiState,
val title: TextReference,
val ticker: TextReference? = null,
val fiatBalance: TextReference? = null,
) : State()
/**
* Unreachable variant dimmed leading texts and a warning badge instead of balances.
*
* @param id Unique id.
* @param icon Token icon state.
* @param title Token name, dimmed.
* @param badge Localized badge label (e.g. `"Unreachable"`).
* @param quote Fiat quote, dimmed. `null` hides it.
* @param priceChange Price change indicator, dimmed. `null` hides it.
* @param onClick Row click handler. `null` with no [onLongClick] makes the row
* non-interactive.
* @param onLongClick Row long-press handler. `null` disables long-press.
*/
data class Unreachable(
override val id: String,
val icon: TangemTokenIcon.UiState,
val title: TextReference,
val badge: TextReference,
val quote: TextReference? = null,
val priceChange: TangemPriceChange.State? = null,
val onClick: (() -> Unit)? = null,
val onLongClick: (() -> Unit)? = null,
) : State()
/**
* No-address variant a tertiary message instead of balances.
*
* @param id Unique id.
* @param icon Token icon state.
* @param title Token name.
* @param message Localized end message (e.g. `"No address"`).
* @param quote Fiat quote. `null` hides it.
* @param priceChange Price change indicator. `null` hides it.
* @param onClick Row click handler. `null` with no [onLongClick] makes the row
* non-interactive.
* @param onLongClick Row long-press handler. `null` disables long-press.
*/
data class NoAddress(
override val id: String,
val icon: TangemTokenIcon.UiState,
val title: TextReference,
val message: TextReference,
val quote: TextReference? = null,
val priceChange: TangemPriceChange.State? = null,
val onClick: (() -> Unit)? = null,
val onLongClick: (() -> Unit)? = null,
) : State()
/**
* Loading variant icon and text-line shimmers.
*
* @param id Unique id.
*/
data class Shimmer(
override val id: String,
) : State()
}
}
/**
* Design-system v2 (DS3) **Token Row** state-driven overload: renders the variant described by
* [TangemTokenRow.State].
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=5723-2473)
*
* @param state Row state model. See [TangemTokenRow.State].
* @param modifier Modifier applied to the row container.
* @param isBalanceHidden When `true`, balances are masked with stars. Kept outside [state] because
* it is an app-wide setting, like in the legacy DS2 row.
* @param dragHandleModifier Modifier applied to the drag-handle icon of the
* [TangemTokenRow.State.Organize] variant (e.g. a reorderable drag-handle modifier); ignored by
* other variants.
*/
@Composable
fun TangemTokenRow(
state: TangemTokenRow.State,
modifier: Modifier = Modifier,
isBalanceHidden: Boolean = false,
dragHandleModifier: Modifier = Modifier,
) {
when (state) {
is TangemTokenRow.State.Content -> TangemTokenRow(
icon = state.icon,
title = state.title,
modifier = modifier,
badge = state.badge,
hasPending = state.hasPending,
quote = state.quote,
priceChange = state.priceChange,
fiatBalance = state.fiatBalance,
cryptoBalance = state.cryptoBalance,
showContractWarning = state.shouldShowContractWarning,
showUpdateWarning = state.shouldShowUpdateWarning,
isBalanceHidden = isBalanceHidden,
isQuoteFlickering = state.isQuoteFlickering,
isBalanceFlickering = state.isBalanceFlickering,
messageBubble = state.messageBubble?.let { bubble -> { TokenRowMessageBubble(bubble = bubble) } },
onClick = state.onClick,
onLongClick = state.onLongClick,
)
is TangemTokenRow.State.Organize -> TangemTokenRow.Organize(
icon = state.icon,
title = state.title,
modifier = modifier,
ticker = state.ticker,
fiatBalance = state.fiatBalance,
isBalanceHidden = isBalanceHidden,
dragHandleModifier = dragHandleModifier,
)
is TangemTokenRow.State.Unreachable -> TangemTokenRow.Unreachable(
icon = state.icon,
title = state.title,
badge = state.badge,
modifier = modifier,
quote = state.quote,
priceChange = state.priceChange,
onClick = state.onClick,
onLongClick = state.onLongClick,
)
is TangemTokenRow.State.NoAddress -> TangemTokenRow.NoAddress(
icon = state.icon,
title = state.title,
message = state.message,
modifier = modifier,
quote = state.quote,
priceChange = state.priceChange,
onClick = state.onClick,
onLongClick = state.onLongClick,
)
is TangemTokenRow.State.Shimmer -> TangemTokenRow.Shimmer(modifier = modifier)
}
}
/** Renders the [TangemTokenRow.MessageBubble] model as a [TangemMessageBubble]. */
@Composable
private fun TokenRowMessageBubble(bubble: TangemTokenRow.MessageBubble) {
TangemMessageBubble(
text = bubble.text,
variant = bubble.variant,
showTip = bubble.shouldShowTip,
icon = bubble.icon,
onClick = bubble.onClick,
onClose = bubble.onClose,
closeContentDescription = bubble.closeContentDescription,
)
}
/**
* Design-system v2 (DS3) **Token Row / Organize** reorder mode: title with a ticker, fiat balance
* underneath and a drag handle at the end.
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=5723-2473)
*
* @param icon Token icon state, rendered at 40dp.
* @param title Token name. Single line, ellipsized.
* @param modifier Modifier applied to the row container.
* @param ticker Currency ticker after the title (e.g. `"BTC"`), baseline-aligned. `null` hides it.
* @param fiatBalance Balance line under the title (e.g. `"$583.00"`). `null` hides it.
* @param isBalanceHidden When `true`, [fiatBalance] is masked with stars.
* @param dragHandleModifier Modifier applied to the drag-handle icon pass the reorderable
* drag-handle modifier here to make the row draggable.
*/
@Composable
fun TangemTokenRow.Organize(
icon: TangemTokenIcon.UiState,
title: TextReference,
modifier: Modifier = Modifier,
ticker: TextReference? = null,
fiatBalance: TextReference? = null,
isBalanceHidden: Boolean = false,
dragHandleModifier: Modifier = Modifier,
) {
TokenRowContainer(modifier = modifier) {
TokenRowHeadIcon(icon = icon)
TokenRowTitleContent(
title = title,
ticker = ticker,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.START_TOP)
.padding(end = 8.dp),
)
if (fiatBalance != null) {
TokenRowCaptionText(
text = fiatBalance,
isBalanceHidden = isBalanceHidden,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.START_BOTTOM)
.padding(end = 8.dp),
)
}
Box(
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.TAIL)
.padding(start = 8.dp)
.size(24.dp)
.then(dragHandleModifier),
contentAlignment = Alignment.Center,
) {
Icon(
imageVector = Icons.ic_sign_equal_24,
contentDescription = null,
tint = TangemTheme.colors3.icon.tertiary,
)
}
}
}
/**
* Design-system v2 (DS3) **Token Row / Unreachable** network-error state: leading texts are
* dimmed to the disabled opacity and a warning badge replaces the balances.
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=5723-2473)
*
* @param icon Token icon state, rendered at 40dp.
* @param title Token name, dimmed. Single line, ellipsized.
* @param badge Localized badge label (e.g. `"Unreachable"`), shown as a warning-tinted badge.
* @param modifier Modifier applied to the row container.
* @param quote Fiat quote, dimmed. `null` hides it.
* @param priceChange Price change indicator, dimmed. `null` hides it.
* @param onClick Row click handler. `null` with no [onLongClick] makes the row non-interactive.
* @param onLongClick Row long-press handler. `null` disables long-press.
*/
@Suppress("LongParameterList")
@Composable
fun TangemTokenRow.Unreachable(
icon: TangemTokenIcon.UiState,
title: TextReference,
badge: TextReference,
modifier: Modifier = Modifier,
quote: TextReference? = null,
priceChange: TangemPriceChange.State? = null,
onClick: (() -> Unit)? = null,
onLongClick: (() -> Unit)? = null,
) {
TokenRowContainer(
modifier = modifier,
onClick = onClick,
onLongClick = onLongClick,
) {
TokenRowHeadIcon(icon = icon)
TokenRowTitleContent(
title = title,
isDimmed = true,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.START_TOP)
.padding(end = 8.dp),
)
if (quote != null || priceChange != null) {
TokenRowSubtitleContent(
quote = quote,
priceChange = priceChange,
isDimmed = true,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.START_BOTTOM)
.padding(end = 8.dp),
)
}
// A single end child has no bottom counterpart, so the container centers it vertically.
TangemBadge(
text = badge,
variant = TangemBadge.Variant.Tinted,
status = TangemBadge.Status.Warning,
size = TangemBadge.Size.X6,
modifier = Modifier.layoutId(layoutId = TokenRowLayoutId.END_TOP),
)
}
}
/**
* Design-system v2 (DS3) **Token Row / No Address** missing-derivation state: a tertiary message
* replaces the balances.
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=5723-2473)
*
* @param icon Token icon state, rendered at 40dp.
* @param title Token name. Single line, ellipsized.
* @param message Localized end message (e.g. `"No address"`), body typography in tertiary color.
* @param modifier Modifier applied to the row container.
* @param quote Fiat quote. `null` hides it.
* @param priceChange Price change indicator. `null` hides it.
* @param onClick Row click handler. `null` with no [onLongClick] makes the row non-interactive.
* @param onLongClick Row long-press handler. `null` disables long-press.
*/
@Suppress("LongParameterList")
@Composable
fun TangemTokenRow.NoAddress(
icon: TangemTokenIcon.UiState,
title: TextReference,
message: TextReference,
modifier: Modifier = Modifier,
quote: TextReference? = null,
priceChange: TangemPriceChange.State? = null,
onClick: (() -> Unit)? = null,
onLongClick: (() -> Unit)? = null,
) {
TokenRowContainer(
modifier = modifier,
onClick = onClick,
onLongClick = onLongClick,
) {
TokenRowHeadIcon(icon = icon)
TokenRowTitleContent(
title = title,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.START_TOP)
.padding(end = 8.dp),
)
if (quote != null || priceChange != null) {
TokenRowSubtitleContent(
quote = quote,
priceChange = priceChange,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.START_BOTTOM)
.padding(end = 8.dp),
)
}
// A single end child has no bottom counterpart, so the container centers it vertically.
Text(
text = message.resolveReference(),
style = TangemTheme.typography3.body.medium,
color = TangemTheme.colors3.text.tertiary,
maxLines = 1,
modifier = Modifier.layoutId(layoutId = TokenRowLayoutId.END_TOP),
)
}
}
/**
* Design-system v2 (DS3) **Token Row / Shimmer** loading placeholder: circular icon shimmer plus
* text-line bars on both sides.
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=5723-2473)
*
* @param modifier Modifier applied to the row container.
*/
@Composable
fun TangemTokenRow.Shimmer(modifier: Modifier = Modifier) {
TokenRowContainer(modifier = modifier) {
TokenRowHeadIcon(icon = TangemTokenIcon.UiState.Shimmer)
TokenRowShimmerLine(
style = TangemTheme.typography3.body.medium,
width = 72.dp,
modifier = Modifier.layoutId(layoutId = TokenRowLayoutId.START_TOP),
)
TokenRowShimmerLine(
style = TangemTheme.typography3.caption.medium,
width = 44.dp,
modifier = Modifier.layoutId(layoutId = TokenRowLayoutId.START_BOTTOM),
)
TokenRowShimmerLine(
style = TangemTheme.typography3.body.medium,
width = 72.dp,
modifier = Modifier.layoutId(layoutId = TokenRowLayoutId.END_TOP),
)
TokenRowShimmerLine(
style = TangemTheme.typography3.caption.medium,
width = 44.dp,
modifier = Modifier.layoutId(layoutId = TokenRowLayoutId.END_BOTTOM),
)
}
}
// region Previews
@Preview(name = "Light", showBackground = true, widthDp = 360)
@Preview(
name = "Dark",
showBackground = true,
widthDp = 360,
uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES,
)
@Composable
private fun TangemTokenRowPreview() {
PreviewContainer { icon ->
TangemTokenRow(
icon = icon,
title = stringReference("Bitcoin"),
badge = TangemTokenRow.Badge(
text = stringReference("APY 5.47%"),
variant = TangemBadge.Variant.Solid,
status = TangemBadge.Status.Info,
),
quote = stringReference("$1.00"),
priceChange = TangemPriceChange.State(
value = stringReference("2.08%"),
direction = TangemPriceChange.Direction.Up,
),
fiatBalance = stringReference("$583.00"),
cryptoBalance = stringReference("0,000015 BTC"),
showContractWarning = true,
showUpdateWarning = true,
messageBubble = {
TangemMessageBubble(
text = stringReference("Enable 5.47% APY on your balance"),
variant = TangemMessageBubble.Variant.Success,
icon = Icons.ic_chart_bar_vertical_16,
onClick = {},
onClose = {},
closeContentDescription = "Dismiss",
)
},
onClick = {},
)
TangemTokenRow(
icon = icon,
title = stringReference("Bitcoin"),
quote = stringReference("$1.00"),
priceChange = TangemPriceChange.State(
value = stringReference("0.4%"),
direction = TangemPriceChange.Direction.Down,
),
fiatBalance = stringReference("$583.00"),
cryptoBalance = stringReference("0,000015 BTC"),
onClick = {},
)
TangemTokenRow.Organize(
icon = icon,
title = stringReference("Bitcoin"),
ticker = stringReference("BTC"),
fiatBalance = stringReference("$583.00"),
)
}
}
@Preview(name = "States Light", showBackground = true, widthDp = 360)
@Preview(
name = "States Dark",
showBackground = true,
widthDp = 360,
uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES,
)
@Composable
private fun TangemTokenRowStatesPreview() {
PreviewContainer { icon ->
TangemTokenRow.Unreachable(
icon = icon,
title = stringReference("Bitcoin"),
badge = stringReference("Unreachable"),
quote = stringReference("$1.00"),
priceChange = TangemPriceChange.State(
value = stringReference("2.08%"),
direction = TangemPriceChange.Direction.Up,
),
)
TangemTokenRow.NoAddress(
icon = icon,
title = stringReference("Bitcoin"),
message = stringReference("No address"),
quote = stringReference("$1.00"),
priceChange = TangemPriceChange.State(
value = stringReference("2.08%"),
direction = TangemPriceChange.Direction.Neutral,
),
)
TangemTokenRow.Shimmer()
}
}
@Composable
private fun PreviewContainer(content: @Composable (icon: TangemTokenIcon.UiState) -> Unit) {
val icon = TangemTokenIcon.UiState.Token(TangemTokenIcon.State(url = null))
TangemThemePreviewRedesign {
Column(modifier = Modifier.background(TangemTheme.colors3.bg.primary)) {
content(icon)
}
}
}
// endregion

View file

@ -0,0 +1,538 @@
@file:Suppress("MagicNumber")
package com.tangem.core.ui.ds2.tokenrow
import androidx.compose.animation.Animatable
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.tween
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.border
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ripple.RippleAlpha
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalRippleConfiguration
import androidx.compose.material3.RippleConfiguration
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.text.applyBladeBrush
import com.tangem.core.ui.ds2.badge.TangemBadge
import com.tangem.core.ui.ds2.loader.TangemLoader
import com.tangem.core.ui.ds2.loader.TangemLoaderSize
import com.tangem.core.ui.ds2.shimmers.TangemShimmer
import com.tangem.core.ui.ds2.tokenicon.TangemTokenIcon
import com.tangem.core.ui.ds2.util.TangemPriceChange
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.conditionalCompose
import com.tangem.core.ui.extensions.orMaskWithStars
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.generated.icons.Icons
import com.tangem.core.ui.res.generated.icons.ic_cloud_exclamation_20
import com.tangem.core.ui.res.generated.icons.ic_warning_20
import kotlin.math.max
/** Content dimming applied to the leading texts of unavailable rows (Figma `opacity/disabled`). */
internal const val TOKEN_ROW_DISABLED_ALPHA = 0.4f
// region Container layout
/** Slot ids of the [TokenRowContainer] custom layout. */
internal enum class TokenRowLayoutId {
HEAD, START_TOP, END_TOP, START_BOTTOM, END_BOTTOM, TAIL, EXTRA_BOTTOM
}
/**
* Token-row container
*
* Policy:
* - HEAD and TAIL are measured first and take their intrinsic width.
* - END slots take the free space left after guaranteeing the START side its minimum width
* (30% of the row for the top line, 32% for the bottom line).
* - START slots fill the remaining width, never shrinking below that minimum.
* - A line with no counterpart on the other axis is vertically centered in the main area.
* - EXTRA_BOTTOM is placed full-width below the main content with an 8dp gap.
*/
@Suppress("LongMethod")
@Composable
internal fun TokenRowContainer(
modifier: Modifier = Modifier,
onClick: (() -> Unit)? = null,
onLongClick: (() -> Unit)? = null,
content: @Composable () -> Unit,
) {
val interactionSource = remember { MutableInteractionSource() }
val isFocused by interactionSource.collectIsFocusedAsState()
val isInteractive = onClick != null || onLongClick != null
val density = LocalDensity.current
val verticalPadding = with(density) { 4.dp.roundToPx() }
val extraContentPadding = with(density) { 8.dp.roundToPx() }
val contentPadding = with(density) { 12.dp.roundToPx() }
val rowModifier = modifier
.conditionalCompose(isFocused) {
border(
width = 2.dp,
color = TangemTheme.colors3.interaction.focusRing.brand,
shape = RoundedCornerShape(4.dp),
)
}
.conditionalCompose(isInteractive) {
combinedClickable(
interactionSource = interactionSource,
indication = LocalIndication.current,
role = Role.Button,
onLongClick = onLongClick,
onClick = onClick ?: {},
)
}
WithTokenRowRipple(enabled = isInteractive) {
Layout(
content = content,
modifier = rowModifier,
) { measurables, constraints ->
val layoutWidth = max(0, constraints.maxWidth - contentPadding * 2)
val startTopMinWidth = (layoutWidth * TITLE_MIN_WIDTH_COEFFICIENT).toInt()
val startBottomMinWidth = (layoutWidth * PRICE_MIN_WIDTH_COEFFICIENT).toInt()
val headPlaceable = measurables.measure(
layoutId = TokenRowLayoutId.HEAD,
constraints = constraints.copy(minWidth = 0),
)
val tailPlaceable = measurables.measure(
layoutId = TokenRowLayoutId.TAIL,
constraints = constraints.copy(minWidth = 0),
)
val availableWidthForBody = layoutWidth - headPlaceable.widthOrZero() - tailPlaceable.widthOrZero()
// End slots take the whole free space but always leave the start side its minimum width.
val endTopPlaceable = measurables.measure(
layoutId = TokenRowLayoutId.END_TOP,
constraints = constraints.copy(
minWidth = 0,
maxWidth = max(0, availableWidthForBody - startTopMinWidth),
),
)
val endBottomPlaceable = measurables.measure(
layoutId = TokenRowLayoutId.END_BOTTOM,
constraints = constraints.copy(
minWidth = 0,
maxWidth = max(0, availableWidthForBody - startBottomMinWidth),
),
)
// Start slots fill the remaining width but never less than their minimum.
val startTopPlaceable = measurables.measure(
layoutId = TokenRowLayoutId.START_TOP,
constraints = constraints.copy(
minWidth = 0,
maxWidth = max(
a = startTopMinWidth,
b = availableWidthForBody - endTopPlaceable.widthOrZero(),
),
),
)
val startBottomPlaceable = measurables.measure(
layoutId = TokenRowLayoutId.START_BOTTOM,
constraints = constraints.copy(
minWidth = 0,
maxWidth = max(
a = startBottomMinWidth,
b = availableWidthForBody - endBottomPlaceable.widthOrZero(),
),
),
)
val extraBottomPlaceable = measurables.measure(
layoutId = TokenRowLayoutId.EXTRA_BOTTOM,
constraints = constraints,
)
val mainLayoutHeight = maxOf(
headPlaceable.heightOrZero(),
tailPlaceable.heightOrZero(),
startTopPlaceable.heightOrZero() + startBottomPlaceable.heightOrZero() + verticalPadding,
endTopPlaceable.heightOrZero() + endBottomPlaceable.heightOrZero() + verticalPadding,
)
val mainContentBottomPadding = if (extraBottomPlaceable != null) {
extraBottomPlaceable.heightOrZero() + contentPadding
} else {
contentPadding
}
val layoutHeight = mainLayoutHeight + contentPadding + mainContentBottomPadding
layout(width = constraints.maxWidth, height = layoutHeight) {
headPlaceable?.placeRelative(
x = contentPadding,
y = contentPadding + (mainLayoutHeight - headPlaceable.height).div(other = 2),
)
startTopPlaceable?.placeRelative(
x = contentPadding + headPlaceable.widthOrZero(),
y = contentPadding + if (startBottomPlaceable == null) {
(mainLayoutHeight - startTopPlaceable.height).div(2)
} else {
0
},
)
startBottomPlaceable?.placeRelative(
x = contentPadding + headPlaceable.widthOrZero(),
y = contentPadding + if (startTopPlaceable == null) {
(mainLayoutHeight - startBottomPlaceable.height).div(2)
} else {
startTopPlaceable.heightOrZero() + verticalPadding
},
)
endTopPlaceable?.placeRelative(
x = layoutWidth - endTopPlaceable.widthOrZero() - tailPlaceable.widthOrZero() + contentPadding,
y = contentPadding + if (endBottomPlaceable == null) {
(mainLayoutHeight - endTopPlaceable.height).div(2)
} else {
0
},
)
endBottomPlaceable?.placeRelative(
x = layoutWidth - endBottomPlaceable.widthOrZero() - tailPlaceable.widthOrZero() + contentPadding,
y = contentPadding + if (endTopPlaceable == null) {
(mainLayoutHeight - endBottomPlaceable.height).div(2)
} else {
endTopPlaceable.heightOrZero() + verticalPadding
},
)
tailPlaceable?.placeRelative(
x = layoutWidth - tailPlaceable.width + contentPadding,
y = contentPadding + (mainLayoutHeight - tailPlaceable.height).div(other = 2),
)
extraBottomPlaceable?.placeRelative(
x = 0,
y = contentPadding + mainLayoutHeight + extraContentPadding,
)
}
}
}
}
private const val TITLE_MIN_WIDTH_COEFFICIENT = 0.3
private const val PRICE_MIN_WIDTH_COEFFICIENT = 0.32
private fun List<Measurable>.measure(layoutId: TokenRowLayoutId, constraints: Constraints): Placeable? {
return firstOrNull { it.layoutId == layoutId }?.measure(constraints)
}
private fun Placeable?.widthOrZero(): Int = this?.width ?: 0
private fun Placeable?.heightOrZero(): Int = this?.height ?: 0
@Composable
private fun WithTokenRowRipple(enabled: Boolean, content: @Composable () -> Unit) {
if (enabled) {
CompositionLocalProvider(LocalRippleConfiguration provides tokenRowRipple(), content = content)
} else {
content()
}
}
@Composable
@ReadOnlyComposable
private fun tokenRowRipple(): RippleConfiguration = RippleConfiguration(
color = TangemTheme.colors3.interaction.press.default,
rippleAlpha = RippleAlpha(
draggedAlpha = 0f,
focusedAlpha = 0f,
hoveredAlpha = 0.05f,
pressedAlpha = 0.1f,
),
)
// endregion
// region Slot contents
/** Head slot: 40dp token icon with the 12dp gap to the content, like the DS2 row. */
@Composable
internal fun TokenRowHeadIcon(icon: TangemTokenIcon.UiState) {
TangemTokenIcon(
state = icon,
size = TangemTokenIcon.Size.X40,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.HEAD)
.padding(end = 12.dp),
)
}
/** Market subtitle line: rank badge (e.g. `2`) and capitalization (e.g. `1.196T`). */
@Composable
internal fun TokenRowMarketSubtitleContent(
position: TextReference?,
capitalization: TextReference?,
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalAlignment = Alignment.CenterVertically,
) {
if (position != null) {
TangemBadge(
text = position,
variant = TangemBadge.Variant.Tinted,
status = TangemBadge.Status.Neutral,
size = TangemBadge.Size.X4,
)
}
if (capitalization != null) {
Text(
text = capitalization.resolveReference(),
style = TangemTheme.typography3.caption.medium,
color = TangemTheme.colors3.text.secondary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
}
}
/**
* Market price line. When [updateDirection] is set, the text flashes in the direction color and
* fades back to primary every time [price] changes ports the live-update blink of the legacy
* `TokenPriceText`. The first composition never blinks.
*/
@Composable
internal fun TokenRowMarketPriceContent(
price: TextReference,
modifier: Modifier = Modifier,
updateDirection: TangemPriceChange.Direction? = null,
) {
val generalColor = TangemTheme.colors3.text.primary
val growColor = TangemTheme.colors3.text.accent.blue
val fallColor = TangemTheme.colors3.text.status.error
val color = remember(generalColor) { Animatable(generalColor) }
var isFirstEmissionSkipped by remember { mutableStateOf(false) }
LaunchedEffect(price) {
if (!isFirstEmissionSkipped) {
isFirstEmissionSkipped = true
return@LaunchedEffect
}
val blinkColor = when (updateDirection) {
TangemPriceChange.Direction.Up -> growColor
TangemPriceChange.Direction.Down -> fallColor
TangemPriceChange.Direction.Neutral, null -> return@LaunchedEffect
}
color.animateTo(blinkColor, snap())
color.animateTo(generalColor, tween(durationMillis = PRICE_BLINK_FADE_DURATION_MILLIS))
}
Text(
text = price.resolveReference(),
style = TangemTheme.typography3.body.medium,
color = color.value,
maxLines = 1,
overflow = TextOverflow.Visible,
modifier = modifier,
)
}
private const val PRICE_BLINK_FADE_DURATION_MILLIS = 500
/** Title line: token name, optional pending-transaction loader, ticker (baseline-aligned), badge. */
@Composable
internal fun TokenRowTitleContent(
title: TextReference,
modifier: Modifier = Modifier,
ticker: TextReference? = null,
badge: TangemTokenRow.Badge? = null,
hasPending: Boolean = false,
isDimmed: Boolean = false,
) {
Row(
modifier = modifier.alpha(if (isDimmed) TOKEN_ROW_DISABLED_ALPHA else 1f),
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = title.resolveReference(),
style = TangemTheme.typography3.body.medium,
color = TangemTheme.colors3.text.primary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier
.weight(weight = 1f, fill = false)
.alignByBaseline(),
)
if (hasPending) {
TangemLoader(
size = TangemLoaderSize.X16,
color = TangemTheme.colors3.icon.tertiary,
)
}
if (ticker != null) {
Text(
text = ticker.resolveReference(),
style = TangemTheme.typography3.caption.medium,
color = TangemTheme.colors3.text.secondary,
maxLines = 1,
modifier = Modifier.alignByBaseline(),
)
}
if (badge != null) {
TangemBadge(
text = badge.text,
variant = badge.variant,
status = badge.status,
size = TangemBadge.Size.X4,
)
}
}
}
/** Subtitle line: quote (e.g. `$1.00`) and the [TangemPriceChange] indicator. */
@Composable
internal fun TokenRowSubtitleContent(
quote: TextReference?,
priceChange: TangemPriceChange.State?,
modifier: Modifier = Modifier,
isDimmed: Boolean = false,
isFlickering: Boolean = false,
) {
Row(
modifier = modifier.alpha(if (isDimmed) TOKEN_ROW_DISABLED_ALPHA else 1f),
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalAlignment = Alignment.CenterVertically,
) {
if (quote != null) {
Text(
text = quote.resolveReference(),
style = TangemTheme.typography3.caption.medium.applyBladeBrush(
isEnabled = isFlickering,
textColor = TangemTheme.colors3.text.secondary,
),
color = TangemTheme.colors3.text.secondary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
if (priceChange != null) {
TangemPriceChange(state = priceChange, isFlickering = isFlickering)
}
}
}
/** Fiat balance with optional contract-error and update-error icons in front of it. */
@Composable
internal fun TokenRowBalanceContent(
fiatBalance: TextReference,
modifier: Modifier = Modifier,
showContractWarning: Boolean = false,
showUpdateWarning: Boolean = false,
isFlickering: Boolean = false,
isBalanceHidden: Boolean = false,
) {
Row(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(2.dp),
verticalAlignment = Alignment.CenterVertically,
) {
if (showContractWarning) {
Icon(
imageVector = Icons.ic_warning_20,
contentDescription = null,
tint = TangemTheme.colors3.icon.status.warning,
modifier = Modifier.size(20.dp),
)
}
if (showUpdateWarning) {
Icon(
imageVector = Icons.ic_cloud_exclamation_20,
contentDescription = null,
tint = TangemTheme.colors3.icon.primary,
modifier = Modifier.size(20.dp),
)
}
Text(
text = fiatBalance.orMaskWithStars(isBalanceHidden).resolveReference(),
style = TangemTheme.typography3.body.medium.applyBladeBrush(
isEnabled = isFlickering,
textColor = TangemTheme.colors3.text.primary,
),
color = TangemTheme.colors3.text.primary,
maxLines = 1,
)
}
}
/** Plain caption line used for secondary amounts (crypto balance, Organize fiat balance). */
@Composable
internal fun TokenRowCaptionText(
text: TextReference,
modifier: Modifier = Modifier,
isFlickering: Boolean = false,
isBalanceHidden: Boolean = false,
) {
Text(
text = text.orMaskWithStars(isBalanceHidden).resolveReference(),
style = TangemTheme.typography3.caption.medium.applyBladeBrush(
isEnabled = isFlickering,
textColor = TangemTheme.colors3.text.secondary,
),
color = TangemTheme.colors3.text.secondary,
maxLines = 1,
modifier = modifier,
)
}
/** Fixed-width shimmer bar sized after a typography line, like the [TangemShimmer] text overload. */
@Composable
internal fun TokenRowShimmerLine(style: TextStyle, width: Dp, modifier: Modifier = Modifier) {
val lineHeight = with(LocalDensity.current) { style.lineHeight.toDp() }
TangemShimmer(
radius = 16.dp,
modifier = modifier
.width(width)
.height(lineHeight)
.padding(vertical = 2.dp),
)
}
// endregion

View file

@ -0,0 +1,315 @@
@file:Suppress("MagicNumber")
package com.tangem.core.ui.ds2.tokenrow
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.ds2.shimmers.TangemShimmer
import com.tangem.core.ui.ds2.tokenicon.TangemTokenIcon
import com.tangem.core.ui.ds2.util.TangemPriceChange
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
/**
* Design-system v2 (DS3) **Token Row Market** a markets-list item: token icon, title with a
* ticker, rank badge + capitalization, price with a [TangemPriceChange] indicator and a trailing
* mini-graph slot.
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=5724-3510&m=dev)
*
* @param icon Token icon state, rendered at 40dp. See [TangemTokenIcon.UiState].
* @param title Token name. Single line, ellipsized.
* @param modifier Modifier applied to the row container.
* @param ticker Currency ticker after the title (e.g. `"BTC"`), baseline-aligned. `null` hides it.
* @param position Market-rank badge label (e.g. `"2"`). `null` hides the badge (Figma `Position`).
* @param capitalization Market capitalization text (e.g. `"1.196T"`). `null` hides it.
* @param price Current price at the end (e.g. `"$59,723.24"`). `null` hides the line.
* @param priceChange Price change indicator under the [price]. `null` hides it.
* @param priceUpdateDirection Direction of the latest live price update. When set, the [price]
* text flashes in the direction color and fades back each time [price] changes. `null` disables
* the flash.
* @param chart Trailing mini-graph slot, vertically centered. `null` hides it.
* @param onClick Row click handler. `null` makes the row non-interactive (no ripple/focus).
*/
@Suppress("LongParameterList")
@Composable
fun TangemTokenRowMarket(
icon: TangemTokenIcon.UiState,
title: TextReference,
modifier: Modifier = Modifier,
ticker: TextReference? = null,
position: TextReference? = null,
capitalization: TextReference? = null,
price: TextReference? = null,
priceChange: TangemPriceChange.State? = null,
priceUpdateDirection: TangemPriceChange.Direction? = null,
chart: (@Composable () -> Unit)? = null,
onClick: (() -> Unit)? = null,
) {
TokenRowContainer(
modifier = modifier,
onClick = onClick,
) {
TangemTokenIcon(
state = icon,
size = TangemTokenIcon.Size.X40,
modifier = Modifier.layoutId(layoutId = TokenRowLayoutId.HEAD),
)
TokenRowTitleContent(
title = title,
ticker = ticker,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.START_TOP)
.padding(start = 12.dp),
)
if (position != null || capitalization != null) {
TokenRowMarketSubtitleContent(
position = position,
capitalization = capitalization,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.START_BOTTOM)
.padding(start = 12.dp),
)
}
if (price != null) {
TokenRowMarketPriceContent(
price = price,
updateDirection = priceUpdateDirection,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.END_TOP)
.padding(start = 12.dp),
)
}
if (priceChange != null) {
TangemPriceChange(
state = priceChange,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.END_BOTTOM)
.padding(start = 12.dp),
)
}
if (chart != null) {
Box(
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.TAIL)
.padding(start = 12.dp),
) {
chart()
}
}
}
}
/**
* Design-system v2 (DS3) **Token Row Market** state-driven overload: renders the variant
* described by [TangemTokenRowMarket.State].
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=5724-3510&m=dev)
*
* @param state Row state model. See [TangemTokenRowMarket.State].
* @param modifier Modifier applied to the row container.
* @param chart Trailing mini-graph slot; only used by [TangemTokenRowMarket.State.Content].
* Stays a slot (not a state field) because the chart component lives in `:common:ui-charts`.
*/
@Composable
fun TangemTokenRowMarket(
state: TangemTokenRowMarket.State,
modifier: Modifier = Modifier,
chart: (@Composable () -> Unit)? = null,
) {
when (state) {
is TangemTokenRowMarket.State.Content -> TangemTokenRowMarket(
icon = state.icon,
title = state.title,
modifier = modifier,
ticker = state.ticker,
position = state.position,
capitalization = state.capitalization,
price = state.price,
priceChange = state.priceChange,
priceUpdateDirection = state.priceUpdateDirection,
chart = chart,
onClick = state.onClick,
)
is TangemTokenRowMarket.State.Shimmer -> TangemTokenRowMarket.Shimmer(modifier = modifier)
}
}
/** Public API surface of [TangemTokenRowMarket]. */
object TangemTokenRowMarket {
/**
* State model of [TangemTokenRowMarket]. Render it with the `TangemTokenRowMarket(state = )`
* overload.
*/
@Immutable
sealed class State {
/** Unique id, e.g. for `LazyColumn` item keys. */
abstract val id: String
/**
* Loaded market row.
*
* @param id Unique id.
* @param icon Token icon state.
* @param title Token name.
* @param ticker Currency ticker after the title. `null` hides it.
* @param position Market-rank badge label. `null` hides the badge.
* @param capitalization Market capitalization text. `null` hides it.
* @param price Current price at the end. `null` hides the line.
* @param priceChange Price change indicator under the price. `null` hides it.
* @param priceUpdateDirection Direction of the latest live price update the price text
* flashes in this color each time [price] changes. `null` disables the flash.
* @param onClick Row click handler. `null` makes the row non-interactive.
*/
data class Content(
override val id: String,
val icon: TangemTokenIcon.UiState,
val title: TextReference,
val ticker: TextReference? = null,
val position: TextReference? = null,
val capitalization: TextReference? = null,
val price: TextReference? = null,
val priceChange: TangemPriceChange.State? = null,
val priceUpdateDirection: TangemPriceChange.Direction? = null,
val onClick: (() -> Unit)? = null,
) : State()
/**
* Loading variant icon and text-line shimmers.
*
* @param id Unique id.
*/
data class Shimmer(
override val id: String,
) : State()
}
}
/**
* Design-system v2 (DS3) **Token Row Market / Shimmer** loading placeholder: circular icon
* shimmer, text-line bars on both sides and a graph-sized bar at the end.
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=5724-3510&m=dev)
*
* @param modifier Modifier applied to the row container.
*/
@Composable
fun TangemTokenRowMarket.Shimmer(modifier: Modifier = Modifier) {
TokenRowContainer(modifier = modifier) {
TangemTokenIcon(
state = TangemTokenIcon.UiState.Shimmer,
size = TangemTokenIcon.Size.X40,
modifier = Modifier.layoutId(layoutId = TokenRowLayoutId.HEAD),
)
TokenRowShimmerLine(
style = TangemTheme.typography3.body.medium,
width = 72.dp,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.START_TOP)
.padding(start = 12.dp),
)
TokenRowShimmerLine(
style = TangemTheme.typography3.caption.medium,
width = 44.dp,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.START_BOTTOM)
.padding(start = 12.dp),
)
TokenRowShimmerLine(
style = TangemTheme.typography3.body.medium,
width = 72.dp,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.END_TOP)
.padding(start = 12.dp),
)
TokenRowShimmerLine(
style = TangemTheme.typography3.caption.medium,
width = 44.dp,
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.END_BOTTOM)
.padding(start = 12.dp),
)
// Graph placeholder — a small bar centered in the 24x32 graph slot.
Box(
modifier = Modifier
.layoutId(layoutId = TokenRowLayoutId.TAIL)
.padding(start = 12.dp)
.size(width = 24.dp, height = 32.dp),
contentAlignment = Alignment.Center,
) {
TangemShimmer(
radius = 4.dp,
modifier = Modifier.size(width = 24.dp, height = 12.dp),
)
}
}
}
// region Previews
@Preview(name = "Light", showBackground = true, widthDp = 360)
@Preview(
name = "Dark",
showBackground = true,
widthDp = 360,
uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES,
)
@Composable
private fun TangemTokenRowMarketPreview() {
TangemThemePreviewRedesign {
Column(modifier = Modifier.background(TangemTheme.colors3.bg.primary)) {
TangemTokenRowMarket(
icon = TangemTokenIcon.UiState.Token(TangemTokenIcon.State(url = null)),
title = stringReference("Bitcoin"),
ticker = stringReference("BTC"),
position = stringReference("2"),
capitalization = stringReference("1.196T"),
price = stringReference("$59,723.24"),
priceChange = TangemPriceChange.State(
value = stringReference("2.08%"),
direction = TangemPriceChange.Direction.Up,
),
chart = { PreviewChartPlaceholder() },
onClick = {},
)
TangemTokenRowMarket(
icon = TangemTokenIcon.UiState.Token(TangemTokenIcon.State(url = null)),
title = stringReference("Very Long Token Name Coin"),
ticker = stringReference("VLTNC"),
capitalization = stringReference("796.9B"),
price = stringReference("$2,591.65"),
priceChange = TangemPriceChange.State(
value = stringReference("0.42%"),
direction = TangemPriceChange.Direction.Down,
),
onClick = {},
)
TangemTokenRowMarket.Shimmer()
}
}
}
@Composable
private fun PreviewChartPlaceholder() {
Box(
modifier = Modifier
.size(width = 24.dp, height = 32.dp)
.background(TangemTheme.colors3.bg.tertiary),
)
}
// endregion

View file

@ -0,0 +1,166 @@
@file:Suppress("MagicNumber")
package com.tangem.core.ui.ds2.util
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.Immutable
import androidx.compose.runtime.NonRestartableComposable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.text.applyBladeBrush
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.TangemThemePreviewRedesign
import com.tangem.core.ui.res.generated.icons.Icons
import com.tangem.core.ui.res.generated.icons.ic_dot_12_filled
import com.tangem.core.ui.res.generated.icons.ic_triangle_down_12
import com.tangem.core.ui.res.generated.icons.ic_triangle_up_12
/**
* Design-system v2 (DS3) **Util / Price Change** a compact directional indicator: an up/down
* triangle (or a dot for [TangemPriceChange.Direction.Neutral]) and a percent label colored by
* [direction]. A "util" building block, not a complete component embed it next to quotes and
* balances (e.g. inside the token row).
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=5724-3922&m=dev)
*
* @param value Formatted percent text (e.g. `"2.08%"`).
* @param direction Change direction driving the arrow and its color. See
* [TangemPriceChange.Direction].
* @param modifier Modifier applied to the indicator root.
* @param isFlickering Runs the blade animation over the label while the value is being refreshed.
*/
@Composable
fun TangemPriceChange(
value: TextReference,
direction: TangemPriceChange.Direction,
modifier: Modifier = Modifier,
isFlickering: Boolean = false,
) {
val textColor = when (direction) {
TangemPriceChange.Direction.Up -> TangemTheme.colors3.text.accent.blue
TangemPriceChange.Direction.Down -> TangemTheme.colors3.text.accent.red
TangemPriceChange.Direction.Neutral -> TangemTheme.colors3.text.tertiary
}
val iconTint = when (direction) {
TangemPriceChange.Direction.Up -> TangemTheme.colors3.icon.accent.blue
TangemPriceChange.Direction.Down -> TangemTheme.colors3.icon.accent.red
TangemPriceChange.Direction.Neutral -> TangemTheme.colors3.icon.tertiary
}
Row(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(2.dp),
verticalAlignment = Alignment.CenterVertically,
) {
val arrow = when (direction) {
TangemPriceChange.Direction.Up -> Icons.ic_triangle_up_12
TangemPriceChange.Direction.Down -> Icons.ic_triangle_down_12
TangemPriceChange.Direction.Neutral -> Icons.ic_dot_12_filled
}
Icon(
imageVector = arrow,
contentDescription = null,
tint = iconTint,
modifier = Modifier.size(12.dp),
)
Text(
text = value.resolveReference(),
style = TangemTheme.typography3.caption.medium.applyBladeBrush(
isEnabled = isFlickering,
textColor = textColor,
),
color = textColor,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
}
/**
* Design-system v2 (DS3) **Util / Price Change** state-driven overload of [TangemPriceChange].
*
* [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=5724-3922&m=dev)
*
* @param state Indicator state model. See [TangemPriceChange.State].
* @param modifier Modifier applied to the indicator root.
* @param isFlickering Runs the blade animation over the label while the value is being refreshed.
*/
@Composable
@NonRestartableComposable
fun TangemPriceChange(state: TangemPriceChange.State, modifier: Modifier = Modifier, isFlickering: Boolean = false) {
TangemPriceChange(
value = state.value,
direction = state.direction,
modifier = modifier,
isFlickering = isFlickering,
)
}
/** Public API surface of [TangemPriceChange]. */
object TangemPriceChange {
/** Direction of the price change, driving the leading icon and its color. */
enum class Direction {
/** Price went up — upward arrow, accent color. */
Up,
/** Price went down — downward arrow, error color. */
Down,
/** No significant change — dot icon, tertiary color. */
Neutral,
}
/**
* Price change state model.
*
* @param value Formatted percent text (e.g. `"2.08%"`).
* @param direction Change direction. See [Direction].
*/
@Immutable
data class State(
val value: TextReference,
val direction: Direction,
)
}
@Preview(name = "Light", showBackground = true)
@Preview(name = "Dark", showBackground = true, uiMode = android.content.res.Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun TangemPriceChangePreview() {
TangemThemePreviewRedesign {
Column(
modifier = Modifier
.background(TangemTheme.colors3.bg.primary)
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
TangemPriceChange.Direction.entries.forEach { direction ->
TangemPriceChange(
value = stringReference("2.08%"),
direction = direction,
)
}
TangemPriceChange(
state = TangemPriceChange.State(
value = stringReference("2.08%"),
direction = TangemPriceChange.Direction.Up,
),
isFlickering = true,
)
}
}
}

View file

@ -304,14 +304,24 @@ fun TextReference.resolveReference(resources: Resources): String {
@Composable
fun TextReference.resolveAnnotatedReference(): AnnotatedString {
return when (this) {
is TextReference.Res -> {
is TextReference.Res -> if (formatArgs.hasAnnotatedArgs()) {
resolveWithAnnotatedArgs(formatArgs = formatArgs, shouldDecapitalize = shouldDecapitalize) { args ->
stringResourceSafe(id = id, *args)
}
} else {
val args = formatArgs.map { if (it is TextReference) it.resolveReference() else it }.toTypedArray()
formatAnnotated(stringResourceSafe(id = id, *args))
}
is TextReference.PluralRes -> formatAnnotated(
pluralStringResourceSafe(id, count, *formatArgs.toTypedArray()),
)
is TextReference.PluralRes -> if (formatArgs.hasAnnotatedArgs()) {
resolveWithAnnotatedArgs(formatArgs = formatArgs) { args ->
pluralStringResourceSafe(id, count, *args)
}
} else {
formatAnnotated(
pluralStringResourceSafe(id, count, *formatArgs.toTypedArray()),
)
}
is TextReference.Str -> formatAnnotated(value)
is TextReference.Annotated -> value
is TextReference.Combined -> buildAnnotatedString {
@ -361,6 +371,60 @@ inline fun TextReference?.isNullOrEmpty(): Boolean {
return this == null || this == TextReference.EMPTY
}
private fun WrappedList<Any>.hasAnnotatedArgs(): Boolean {
return any { it is AnnotatedString || it is TextReference.Annotated }
}
/**
* Resolves a formatted resource whose [formatArgs] may carry annotations (span styles, inline content).
*
* Annotated args are substituted with sentinel tokens for the locale-aware formatting pass performed by
* [formatTemplate] (so `%d`, positional `%1$s` reordering and `%%` escapes still work) and then spliced back
* with their annotations preserved. Literal template text is appended verbatim markdown is not parsed on
* this path.
*/
@Composable
private fun resolveWithAnnotatedArgs(
formatArgs: WrappedList<Any>,
shouldDecapitalize: Boolean = false,
formatTemplate: @Composable (args: Array<Any>) -> String,
): AnnotatedString {
val annotatedArgs = mutableMapOf<Int, AnnotatedString>()
val plainArgs = formatArgs.mapIndexed { index, arg ->
val annotated = when (arg) {
is AnnotatedString -> arg
is TextReference.Annotated -> arg.value
else -> null
}
when {
annotated != null -> {
annotatedArgs[index] = annotated
"$ANNOTATED_ARG_SENTINEL$index$ANNOTATED_ARG_SENTINEL"
}
arg is TextReference -> arg.resolveReference()
else -> arg
}
}.toTypedArray()
val formatted = formatTemplate(plainArgs).let { resolved ->
if (shouldDecapitalize) resolved.replaceFirstChar { char -> char.lowercase() } else resolved
}
return buildAnnotatedString {
var literalStart = 0
annotatedArgSentinelRegex.findAll(formatted).forEach { match ->
append(formatted.substring(literalStart, match.range.first))
annotatedArgs[match.groupValues[1].toInt()]?.let(::append)
literalStart = match.range.last + 1
}
append(formatted.substring(literalStart))
}
}
// OBJECT REPLACEMENT CHARACTER — never occurs in resource strings, so it can't clash with formatted output
private const val ANNOTATED_ARG_SENTINEL = ''
private val annotatedArgSentinelRegex = Regex("(\\d+)")
@Composable
private fun formatAnnotated(rawString: String): AnnotatedString {
val markdownDescriptor = rememberMarkdownParser()

View file

@ -52,11 +52,13 @@ open class BigDecimalCryptoFormatStyled(
fun BigDecimalFormatScope.crypto(
symbol: String,
decimals: Int,
ignoreSymbolPosition: Boolean = false,
locale: Locale = Locale.getDefault(),
): BigDecimalCryptoFormat {
return BigDecimalCryptoFormat(
symbol = symbol,
decimals = decimals,
shouldIgnoreSymbolPosition = ignoreSymbolPosition,
locale = locale,
)
}

View file

@ -6,9 +6,6 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SnackbarResult
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -28,10 +25,6 @@ import com.tangem.core.ui.res.*
@Composable
fun EventMessageEffect(
messageHandler: EventMessageHandler = LocalEventMessageHandler.current,
snackbarHostState: SnackbarHostState = LocalSnackbarHostState.current,
onShowSnackbar: suspend (SnackbarMessage, Context) -> Unit = { message, context ->
showSnackbar(snackbarHostState, message, context)
},
topSnackbarHostState: TangemTopSnackbarHostState = LocalTopSnackbarHostState.current,
onShowTopSnackbar: suspend (SnackbarMessage) -> Unit = { message ->
topSnackbarHostState.showSnackbar(message)
@ -44,16 +37,11 @@ fun EventMessageEffect(
var dialogMessage: DialogMessage? by remember { mutableStateOf(value = null) }
var bottomSheetMessage: BottomSheetMessage? by remember { mutableStateOf(value = null) }
var loadingMessage: GlobalLoadingMessage? by remember { mutableStateOf(value = null) }
val isRedesignEnabled = LocalRedesignEnabled.current
EventEffect(event = messageEvent) { message ->
when (message) {
is SnackbarMessage -> {
if (isRedesignEnabled) {
onShowTopSnackbar(message)
} else {
onShowSnackbar(message, context)
}
onShowTopSnackbar(message)
}
is DialogMessage -> {
dialogMessage = message
@ -155,23 +143,6 @@ private fun MessageDialog(message: DialogMessage, onDismissRequest: () -> Unit)
)
}
private suspend fun showSnackbar(snackbarHostState: SnackbarHostState, message: SnackbarMessage, context: Context) {
val result = snackbarHostState.showSnackbar(
message = message.message.resolveReference(context.resources),
actionLabel = message.actionLabel?.resolveReference(context.resources),
duration = when (message.duration) {
SnackbarMessage.Duration.Short -> SnackbarDuration.Short
SnackbarMessage.Duration.Long -> SnackbarDuration.Long
SnackbarMessage.Duration.Indefinite -> SnackbarDuration.Indefinite
},
)
when (result) {
SnackbarResult.Dismissed -> message.onDismissRequest()
SnackbarResult.ActionPerformed -> message.action?.invoke()
}
}
private fun showToast(message: ToastMessage, context: Context) {
Toast.makeText(
/* context = */ context,

View file

@ -65,11 +65,7 @@ fun TangemTheme(
typography = typography,
dimens = dimens,
content = {
if (uiDependencies.designFeatureToggles.isRedesignEnabled) {
TangemThemeRedesign { content() }
} else {
content()
}
TangemThemeRedesign { content() }
},
)
}
@ -452,14 +448,6 @@ val LocalHazeState = staticCompositionLocalOf<HazeState> {
error("No HazeState provided")
}
val LocalRedesignEnabled = staticCompositionLocalOf<Boolean> {
false
}
val LocalVisaRedesignEnabled = staticCompositionLocalOf<Boolean> {
false
}
val LocalPowerSavingState = compositionLocalOf<PowerSavingState> {
error("No PowerSavingState provided")
}

View file

@ -37,7 +37,6 @@ fun TangemThemeRedesign(content: @Composable () -> Unit) {
colorScheme = tangemColorScheme(colors = rememberedColors),
) {
CompositionLocalProvider(
LocalRedesignEnabled provides true,
LocalTangemColors provides rememberedColors,
LocalTangemColors2 provides if (LocalIsInDarkTheme.current) darkThemeColors2() else lightThemeColors2(),
LocalTangemColors3 provides rememberedColors3,

View file

@ -1 +1 @@
d90598b8786899b4dbdd8f8744c24c13ea8a9545971b0f20c1c2136be83e63be
977ce9a11a9c9aae8b607f63f94e50983f3403d06dc552943fff74d91ff0d2ce

View file

@ -0,0 +1 @@
4127e6bef1d16ebcd2688aff883dbf08ede367ea90f6a3976dffa377c02b0062

View file

@ -0,0 +1,48 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.assets
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.res.generated.icons.Icons
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _il_token_custom: ImageVector? = null
val Icons.il_token_custom: ImageVector
get() {
if (_il_token_custom != null) return _il_token_custom!!
_il_token_custom = ImageVector.Builder(
name = "il_token_custom",
defaultWidth = 72.dp,
defaultHeight = 72.dp,
viewportWidth = 72f,
viewportHeight = 72f,
).apply {
addPath(
fill = SolidColor(Color(0xFF989898)),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M36 16L37.7316 27.2942C38.2833 30.8928 41.1072 33.7167 44.7058 34.2684L56 36L44.7058 37.7316C41.1072 38.2833 38.2833 41.1072 37.7316 44.7058L36 56L34.2684 44.7058C33.7167 41.1072 30.8928 38.2833 27.2942 37.7316L16 36L27.2942 34.2684C30.8928 33.7167 33.7167 30.8928 34.2684 27.2942L36 16Z"),
)
}.build()
return _il_token_custom!!
}
@Composable
@Preview(showBackground = true)
private fun IlTokenCustomPreview() {
Icon(
imageVector = Icons.il_token_custom,
contentDescription = null,
)
}

View file

@ -0,0 +1,53 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.assets
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.res.generated.icons.Icons
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _il_token_error: ImageVector? = null
val Icons.il_token_error: ImageVector
get() {
if (_il_token_error != null) return _il_token_error!!
_il_token_error = ImageVector.Builder(
name = "il_token_error",
defaultWidth = 72.dp,
defaultHeight = 72.dp,
viewportWidth = 72f,
viewportHeight = 72f,
).apply {
addPath(
fill = SolidColor(Color(0xFF989898)),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M35.9878 28.0059C36.1308 28.1328 36.2045 28.8048 36.2465 29.0355C36.489 30.3678 36.5924 31.7421 36.9527 33.0485C37.1171 33.645 37.5014 34.1627 37.9998 34.5013C38.824 35.1346 39.782 35.126 40.7125 35.3368C41.7693 35.5763 42.8366 35.6241 43.878 35.8204C42.8585 35.9143 41.7673 36.0899 40.7596 36.2732C40.176 36.3793 39.6277 36.4243 39.0557 36.6109C38.6851 36.7296 38.3339 36.9069 38.0151 37.1361C36.6891 38.076 36.7863 39.6009 36.491 41.0878C36.3871 41.6108 36.3229 42.1513 36.2334 42.6776C36.1768 43.0103 36.1778 43.3665 36.116 43.6962L36.1106 43.7247C35.9884 43.5741 35.9381 42.6806 35.9 42.4375C35.8158 41.8984 35.7348 41.3491 35.6369 40.8104C35.4512 39.8562 35.4291 38.6253 34.8496 37.8214C34.0091 36.6554 32.6573 36.4726 31.376 36.2644C30.3 36.0896 29.2284 35.9653 28.1589 35.7995C28.5816 35.7323 29.0428 35.7299 29.4714 35.6679C30.0937 35.58 30.7226 35.4601 31.3409 35.3511C32.5544 35.1322 33.7541 35.0925 34.6237 34.0518C35.3745 33.2323 35.3419 32.2197 35.559 31.2108C35.7972 30.1045 35.8495 29.1136 35.9878 28.0059Z"),
)
addPath(
fill = SolidColor(Color(0xFF989898)),
pathFillType = PathFillType.EvenOdd,
pathData = addPathNodes("M35.9998 18.1596C42.7132 15.1312 49.2667 15.1891 53.039 18.9612C56.8112 22.7333 56.8678 29.2859 53.8395 35.9991C56.8686 42.7129 56.8115 49.2668 53.039 53.0392L52.7638 53.3023C48.9535 56.8111 42.5535 56.7952 36.0009 53.8396C29.2871 56.8685 22.733 56.8115 18.9606 53.0392L18.6975 52.7629C15.1887 48.9527 15.2035 42.5526 18.1591 36.0002C15.1308 29.287 15.1896 22.7333 18.9617 18.9612C22.7339 15.1894 29.2868 15.1315 35.9998 18.1596ZM19.5045 38.6361C19.1888 39.4941 18.9313 40.3404 18.7336 41.1678C17.646 45.7219 18.4171 49.318 20.5494 51.4504C22.6819 53.5829 26.2788 54.3551 30.8332 53.2673C31.6604 53.0697 32.5061 52.811 33.3639 52.4953C30.667 50.958 27.9994 48.9357 25.5318 46.4681C23.0642 44.0005 21.0418 41.333 19.5045 38.6361ZM52.4952 38.635C50.9578 41.332 48.9366 44.0004 46.469 46.4681C44.0013 48.9357 41.3328 50.9568 38.6357 52.4943C39.4942 52.8101 40.3408 53.0685 41.1686 53.2662C45.7225 54.3537 49.3189 53.5836 51.4513 51.4515C53.5838 49.3191 54.3548 45.722 53.2671 41.1678C53.0694 40.3401 52.8111 39.4933 52.4952 38.635ZM35.9998 20.6431C32.9921 22.1337 29.9331 24.3053 27.1195 27.1188C24.306 29.9323 22.1345 32.9914 20.6437 35.9991C22.1343 39.007 24.3056 42.0665 27.1195 44.8804C29.933 47.6939 32.9921 49.8653 35.9998 51.3561C39.0076 49.8651 42.0674 47.6942 44.8813 44.8804C47.6952 42.0665 49.8662 39.0069 51.357 35.9991C49.866 32.9916 47.6937 29.9334 44.8802 27.1199C42.0663 24.3062 39.0076 22.134 35.9998 20.6431ZM51.4513 20.5488C49.3188 18.4165 45.7218 17.6464 41.1675 18.7342C40.3402 18.9318 39.4937 19.1883 38.6357 19.5039C41.3329 21.0413 44.0012 23.0634 46.469 25.5312C48.9366 27.9988 50.9578 30.6673 52.4952 33.3643C52.8109 32.5063 53.0695 31.66 53.2671 30.8326C54.3548 26.2784 53.5838 22.6812 51.4513 20.5488ZM30.8332 18.7331C26.2789 17.6453 22.6819 18.4175 20.5494 20.5499C18.4172 22.6824 17.647 26.2784 18.7347 30.8326C18.9322 31.6593 19.1891 32.5048 19.5045 33.3621C21.0417 30.6655 23.0645 27.9985 25.5318 25.5312C27.9994 23.0636 30.667 21.0412 33.3639 19.5039C32.5062 19.1884 31.6603 18.9307 30.8332 18.7331Z"),
)
}.build()
return _il_token_error!!
}
@Composable
@Preview(showBackground = true)
private fun IlTokenErrorPreview() {
Icon(
imageVector = Icons.il_token_error,
contentDescription = null,
)
}

View file

@ -1 +1 @@
023a0f2a00de6fcd99f046ded7f648786a000cf1b10b70e17c78b1efed9e63f6
584afefd9e15a51e0b0075d94045ec3a1b3d76bbedadc4780f858ce82dfffe76

View file

@ -31,7 +31,7 @@ val Icons.ic_address_polygon_16: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M4.53711 2.69414C5.02195 2.43596 5.60404 2.43592 6.08887 2.69414L7.75195 3.57988C8.28964 3.86657 8.62591 4.42656 8.62598 5.03594V5.49492C8.62547 5.83958 8.34573 6.11979 8.00098 6.11992C7.65613 6.1199 7.37649 5.83965 7.37598 5.49492V5.03594C7.37591 4.88841 7.29414 4.75294 7.16406 4.6834L5.50098 3.79766C5.38347 3.73507 5.24252 3.73512 5.125 3.79766L3.46191 4.6834C3.3317 4.7529 3.25007 4.88833 3.25 5.03594V7.38457C3.2502 7.53207 3.33176 7.66767 3.46191 7.73711L5.125 8.62285C5.24241 8.68521 5.3836 8.6853 5.50098 8.62285L9.91309 6.27324C10.3979 6.01506 10.98 6.01502 11.4648 6.27324L13.1279 7.15898C13.6656 7.44565 14.0019 8.00567 14.002 8.61504V10.9637C14.0018 11.573 13.6656 12.1331 13.1279 12.4197L11.4648 13.3055C10.9801 13.5636 10.3978 13.5635 9.91309 13.3055L8.25 12.4197C7.71226 12.1331 7.37617 11.573 7.37598 10.9637V10.5057C7.37598 10.1605 7.65581 9.88068 8.00098 9.88066C8.34604 9.8808 8.62598 10.1606 8.62598 10.5057V10.9637C8.62617 11.1113 8.70759 11.2478 8.83789 11.3172L10.501 12.2029C10.6183 12.2652 10.7597 12.2652 10.877 12.2029L12.54 11.3172C12.6703 11.2478 12.7518 11.1112 12.752 10.9637V8.61504C12.7519 8.46752 12.6701 8.33202 12.54 8.2625L10.877 7.37676C10.7595 7.31417 10.6185 7.31422 10.501 7.37676L6.08887 9.72637C5.60417 9.98446 5.02184 9.98437 4.53711 9.72637L2.87402 8.84062C2.33626 8.55404 2.0002 7.99392 2 7.38457V5.03594C2.00007 4.42648 2.3362 3.86654 2.87402 3.57988L4.53711 2.69414Z"),
pathData = addPathNodes("M4.53711 2.69414C5.02195 2.43596 5.60404 2.43592 6.08887 2.69414L7.75195 3.57988C8.28964 3.86657 8.62591 4.42656 8.62598 5.03594V5.49492C8.62547 5.83958 8.34573 6.11979 8.00098 6.11992C7.65613 6.1199 7.37649 5.83965 7.37598 5.49492V5.03594C7.37591 4.88841 7.29414 4.75294 7.16406 4.6834L5.50098 3.79766C5.38347 3.73507 5.24252 3.73512 5.125 3.79766L3.46191 4.6834C3.3317 4.7529 3.25007 4.88833 3.25 5.03594V7.38457C3.2502 7.53207 3.33176 7.66767 3.46191 7.73711L5.125 8.62285C5.24241 8.68521 5.3836 8.6853 5.50098 8.62285L9.91309 6.27324C10.3979 6.01506 10.98 6.01502 11.4648 6.27324L13.1279 7.15898C13.6656 7.44565 14.0019 8.00568 14.002 8.61504V10.9637C14.0018 11.573 13.6656 12.1331 13.1279 12.4197L11.4648 13.3055C10.9801 13.5636 10.3978 13.5635 9.91309 13.3055L8.25 12.4197C7.71226 12.1331 7.37617 11.573 7.37598 10.9637V10.5057C7.37598 10.1605 7.65581 9.88068 8.00098 9.88066C8.34604 9.88079 8.62598 10.1606 8.62598 10.5057V10.9637C8.62617 11.1113 8.70759 11.2478 8.83789 11.3172L10.501 12.2029C10.6183 12.2652 10.7597 12.2652 10.877 12.2029L12.54 11.3172C12.6703 11.2478 12.7518 11.1112 12.752 10.9637V8.61504C12.7519 8.46752 12.6701 8.33202 12.54 8.2625L10.877 7.37676C10.7595 7.31417 10.6185 7.31422 10.501 7.37676L6.08887 9.72637C5.60417 9.98446 5.02184 9.98437 4.53711 9.72637L2.87402 8.84062C2.33626 8.55404 2.0002 7.99392 2 7.38457V5.03594C2.00007 4.42648 2.3362 3.86654 2.87402 3.57988L4.53711 2.69414Z"),
)
}.build()
return _ic_address_polygon_16!!

View file

@ -31,7 +31,7 @@ val Icons.ic_address_polygon_20: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M5.78125 3.21402C6.30813 2.92909 6.94286 2.92905 7.46973 3.21402L9.82031 4.48453C10.3935 4.79465 10.751 5.39437 10.751 6.04605V6.80484C10.7504 7.21849 10.4147 7.55467 10.001 7.55484C9.5871 7.55484 9.25152 7.21859 9.25098 6.80484V6.04605C9.25095 5.94518 9.19511 5.85194 9.10645 5.80386L6.75586 4.53335C6.67424 4.48924 6.57575 4.48921 6.49414 4.53335L4.14453 5.80386C4.05587 5.85194 4.00002 5.94518 4 6.04605V9.38882C4.00037 9.48941 4.05601 9.58215 4.14453 9.63003L6.49414 10.9015C6.57557 10.9455 6.6744 10.9454 6.75586 10.9015L12.5312 7.7775C13.0582 7.4925 13.6938 7.4925 14.2207 7.7775L16.5703 9.04898C17.1435 9.35911 17.501 9.9588 17.501 10.6105V13.9523C17.5008 14.6039 17.1434 15.2038 16.5703 15.5138L14.2207 16.7853C13.6939 17.0701 13.058 17.0701 12.5312 16.7853L10.1816 15.5138C9.6085 15.2038 9.25119 14.6039 9.25098 13.9523V13.1945C9.25098 12.7803 9.58676 12.4445 10.001 12.4445C10.415 12.4447 10.751 12.7804 10.751 13.1945V13.9523C10.7512 14.053 10.806 14.1465 10.8945 14.1945L13.2451 15.466C13.3266 15.5099 13.4254 15.5099 13.5068 15.466L15.8574 14.1945C15.946 14.1465 16.0008 14.053 16.001 13.9523V10.6105C16.001 10.5097 15.946 10.4164 15.8574 10.3683L13.5068 9.09683C13.4253 9.05275 13.3267 9.05274 13.2451 9.09683L7.46973 12.2209C6.94305 12.5056 6.30796 12.5055 5.78125 12.2209L3.43066 10.9494C2.85767 10.6394 2.50037 10.0402 2.5 9.38882V6.04605C2.50002 5.39437 2.85752 4.79465 3.43066 4.48453L5.78125 3.21402Z"),
pathData = addPathNodes("M5.78125 3.21402C6.30813 2.92909 6.94286 2.92905 7.46973 3.21402L9.82031 4.48453C10.3935 4.79465 10.751 5.39437 10.751 6.04605V6.80484C10.7504 7.21849 10.4147 7.55467 10.001 7.55484C9.5871 7.55484 9.25152 7.21859 9.25098 6.80484V6.04605C9.25095 5.94518 9.19511 5.85194 9.10645 5.80386L6.75586 4.53335C6.67424 4.48924 6.57575 4.48921 6.49414 4.53335L4.14453 5.80386C4.05587 5.85194 4.00002 5.94518 4 6.04605V9.38882C4.00037 9.48941 4.056 9.58215 4.14453 9.63003L6.49414 10.9015C6.57557 10.9455 6.6744 10.9454 6.75586 10.9015L12.5312 7.7775C13.0582 7.4925 13.6938 7.4925 14.2207 7.7775L16.5703 9.04898C17.1435 9.35911 17.501 9.9588 17.501 10.6105V13.9523C17.5008 14.6039 17.1434 15.2038 16.5703 15.5138L14.2207 16.7853C13.6939 17.0701 13.058 17.0701 12.5312 16.7853L10.1816 15.5138C9.6085 15.2038 9.25119 14.6039 9.25098 13.9523V13.1945C9.25098 12.7803 9.58676 12.4445 10.001 12.4445C10.415 12.4447 10.751 12.7804 10.751 13.1945V13.9523C10.7512 14.053 10.806 14.1465 10.8945 14.1945L13.2451 15.466C13.3266 15.5099 13.4254 15.5099 13.5068 15.466L15.8574 14.1945C15.946 14.1465 16.0008 14.053 16.001 13.9523V10.6105C16.001 10.5097 15.946 10.4164 15.8574 10.3683L13.5068 9.09683C13.4253 9.05275 13.3267 9.05274 13.2451 9.09683L7.46973 12.2209C6.94305 12.5056 6.30796 12.5055 5.78125 12.2209L3.43066 10.9494C2.85767 10.6394 2.50037 10.0402 2.5 9.38882V6.04605C2.50002 5.39437 2.85752 4.79465 3.43066 4.48453L5.78125 3.21402Z"),
)
}.build()
return _ic_address_polygon_20!!

View file

@ -31,7 +31,7 @@ val Icons.ic_arrow_refresh_12: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M9.96777 5.4668C10.2623 5.4668 10.501 5.70545 10.501 6C10.501 8.48579 8.48581 10.501 6 10.501C4.62026 10.5007 3.39017 9.87706 2.56641 8.90039V9.30664C2.56606 9.6009 2.32754 9.83984 2.0332 9.83984C1.73913 9.83953 1.50035 9.6007 1.5 9.30664V7.65332C1.5 7.35896 1.73892 7.12043 2.0332 7.12012H3.68652C3.98107 7.12012 4.21973 7.35877 4.21973 7.65332C4.21954 7.94772 3.98096 8.18652 3.68652 8.18652H3.35938C3.98887 8.94784 4.93716 9.43331 6 9.43359C7.89672 9.43359 9.43457 7.89668 9.43457 6C9.43457 5.7056 9.67344 5.46705 9.96777 5.4668Z"),
pathData = addPathNodes("M9.96777 5.4668C10.2623 5.4668 10.501 5.70545 10.501 6C10.501 8.48579 8.48581 10.501 6 10.501C4.62026 10.5007 3.39017 9.87706 2.56641 8.90039V9.30664C2.56606 9.6009 2.32754 9.83984 2.0332 9.83984C1.73913 9.83953 1.50035 9.6007 1.5 9.30664V7.65332C1.5 7.35896 1.73892 7.12043 2.0332 7.12012H3.68652C3.98107 7.12012 4.21973 7.35877 4.21973 7.65332C4.21954 7.94772 3.98096 8.18652 3.68652 8.18652H3.35938C3.98887 8.94784 4.93716 9.43331 6 9.43359C7.89672 9.43359 9.43457 7.89668 9.43457 6C9.43457 5.7056 9.67343 5.46705 9.96777 5.4668Z"),
)
addPath(
fill = SolidColor(Color.Black),

View file

@ -31,7 +31,7 @@ val Icons.ic_arrow_refresh_16: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M12.8789 7.37695C13.224 7.37704 13.5039 7.65683 13.5039 8.00195C13.5039 11.0407 11.0407 13.5038 8.00195 13.5039C6.28439 13.5039 4.7571 12.713 3.75 11.4814V12.0664C3.74971 12.4113 3.46988 12.6913 3.125 12.6914C2.7801 12.6913 2.50029 12.4113 2.5 12.0664V10.0342C2.5 9.68907 2.77992 9.4093 3.125 9.40918H5.15723C5.50229 9.40932 5.78223 9.68909 5.78223 10.0342C5.78207 10.3791 5.50219 10.659 5.15723 10.6592H4.69141C5.47041 11.6307 6.66264 12.2539 8.00195 12.2539C10.3503 12.2538 12.2539 10.3503 12.2539 8.00195C12.2539 7.65677 12.5337 7.37695 12.8789 7.37695Z"),
pathData = addPathNodes("M12.8789 7.37695C13.224 7.37704 13.5039 7.65683 13.5039 8.00195C13.5039 11.0407 11.0407 13.5038 8.00195 13.5039C6.28439 13.5039 4.7571 12.713 3.75 11.4814V12.0664C3.74971 12.4113 3.46988 12.6913 3.125 12.6914C2.7801 12.6913 2.50029 12.4113 2.5 12.0664V10.0342C2.5 9.68908 2.77992 9.4093 3.125 9.40918H5.15723C5.50229 9.40932 5.78223 9.68909 5.78223 10.0342C5.78207 10.3791 5.50219 10.659 5.15723 10.6592H4.69141C5.47041 11.6307 6.66264 12.2539 8.00195 12.2539C10.3503 12.2538 12.2539 10.3503 12.2539 8.00195C12.2539 7.65678 12.5337 7.37695 12.8789 7.37695Z"),
)
addPath(
fill = SolidColor(Color.Black),

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_arrow_split_top_16: ImageVector? = null
val Icons.ic_arrow_split_top_16: ImageVector
get() {
if (_ic_arrow_split_top_16 != null) return _ic_arrow_split_top_16!!
_ic_arrow_split_top_16 = ImageVector.Builder(
name = "ic_arrow_split_top_16",
defaultWidth = 16.dp,
defaultHeight = 16.dp,
viewportWidth = 16f,
viewportHeight = 16f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M3.66278 6.15311C3.34703 6.55766 2.93 6.40893 2.78107 5.89134L2.03041 3.31528C1.91126 2.90477 2.16148 2.58351 2.59042 2.60136L5.27728 2.6906C5.81346 2.70844 6.05176 3.08325 5.74197 3.48186L5.20579 4.16603L5.22962 4.17793C6.32581 4.90375 7.66626 6.41488 7.98796 7.41436H8.01179C8.32755 6.42083 9.67395 4.90375 10.7701 4.17793L10.7999 4.16008L10.2518 3.40452C9.95396 2.99401 10.1982 2.62515 10.7404 2.6311L13.4272 2.6192C13.8562 2.6192 14.0945 2.95237 13.9634 3.36287L13.1293 5.90918C12.9685 6.42083 12.5395 6.55766 12.2357 6.13526L11.6578 5.33805L11.5267 5.42134C10.3293 6.18285 8.72074 8.05689 8.72074 9.41929V12.6022C8.72074 13.1198 8.46457 13.3994 7.99988 13.3994C7.53519 13.3994 7.28497 13.1198 7.28497 12.6022V9.41929C7.28497 8.05689 5.66452 6.18285 4.47301 5.42134L4.31216 5.3202L3.66278 6.15311Z"),
)
}.build()
return _ic_arrow_split_top_16!!
}
@Composable
@Preview(showBackground = true)
private fun IcArrowSplitTop16Preview() {
Icon(
imageVector = Icons.ic_arrow_split_top_16,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_arrow_split_top_20: ImageVector? = null
val Icons.ic_arrow_split_top_20: ImageVector
get() {
if (_ic_arrow_split_top_20 != null) return _ic_arrow_split_top_20!!
_ic_arrow_split_top_20 = ImageVector.Builder(
name = "ic_arrow_split_top_20",
defaultWidth = 20.dp,
defaultHeight = 20.dp,
viewportWidth = 20f,
viewportHeight = 20f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M4.21632 7.53715C3.79528 8.07662 3.23917 7.87829 3.04056 7.18808L2.03958 3.75294C1.88069 3.20553 2.21435 2.77713 2.78635 2.80093L6.36924 2.91993C7.08423 2.94373 7.402 3.44354 6.98889 3.97507L6.27391 4.88741L6.30568 4.90327C7.76744 5.87115 9.55491 7.88622 9.98391 9.21902H10.0157C10.4367 7.89415 12.2321 5.87115 13.6939 4.90327L13.7336 4.87947L13.0027 3.87194C12.6055 3.32454 12.9312 2.83267 13.6542 2.8406L17.2371 2.82473C17.8091 2.82473 18.1268 3.269 17.9521 3.8164L16.8399 7.21188C16.6254 7.89415 16.0534 8.07662 15.6482 7.51335L14.8776 6.45028L14.7028 6.56135C13.106 7.57682 10.9611 10.0758 10.9611 11.8926V16.1369C10.9611 16.8271 10.6195 17.2 9.99979 17.2C9.38014 17.2 9.04647 16.8271 9.04647 16.1369V11.8926C9.04647 10.0758 6.88562 7.57682 5.29675 6.56135L5.08226 6.42648L4.21632 7.53715Z"),
)
}.build()
return _ic_arrow_split_top_20!!
}
@Composable
@Preview(showBackground = true)
private fun IcArrowSplitTop20Preview() {
Icon(
imageVector = Icons.ic_arrow_split_top_20,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_arrow_split_top_24: ImageVector? = null
val Icons.ic_arrow_split_top_24: ImageVector
get() {
if (_ic_arrow_split_top_24 != null) return _ic_arrow_split_top_24!!
_ic_arrow_split_top_24 = ImageVector.Builder(
name = "ic_arrow_split_top_24",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M4.77041 8.92145C4.24409 9.59579 3.54897 9.34787 3.30071 8.48512L2.04947 4.19119C1.85087 3.50693 2.26794 2.97143 2.98293 3.00118L7.46155 3.14993C8.35528 3.17968 8.7525 3.80444 8.23612 4.46885L7.34238 5.60928L7.3821 5.62911C9.2093 6.83895 11.4436 9.35779 11.9799 11.0238H12.0196C12.5459 9.36771 14.7902 6.83895 16.6174 5.62911L16.667 5.59936L15.7534 4.33994C15.2569 3.65568 15.6641 3.04085 16.5677 3.05077L21.0463 3.03093C21.7613 3.03093 22.1585 3.58627 21.9401 4.27052L20.5498 8.51487C20.2817 9.36771 19.5667 9.59579 19.0603 8.8917L18.097 7.56287L17.8785 7.7017C15.8825 8.97104 13.2013 12.0948 13.2013 14.3657V19.6712C13.2013 20.5339 12.7743 21 11.9997 21C11.2252 21 10.8081 20.5339 10.8081 19.6712V14.3657C10.8081 12.0948 8.10702 8.97104 6.12094 7.7017L5.85282 7.53312L4.77041 8.92145Z"),
)
}.build()
return _ic_arrow_split_top_24!!
}
@Composable
@Preview(showBackground = true)
private fun IcArrowSplitTop24Preview() {
Icon(
imageVector = Icons.ic_arrow_split_top_24,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_arrow_split_top_28: ImageVector? = null
val Icons.ic_arrow_split_top_28: ImageVector
get() {
if (_ic_arrow_split_top_28 != null) return _ic_arrow_split_top_28!!
_ic_arrow_split_top_28 = ImageVector.Builder(
name = "ic_arrow_split_top_28",
defaultWidth = 28.dp,
defaultHeight = 28.dp,
viewportWidth = 28f,
viewportHeight = 28f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M5.32449 10.3058C4.69291 11.115 3.85876 10.8175 3.56085 9.78216L2.05937 4.62944C1.82104 3.80833 2.32153 3.16573 3.17952 3.20143L8.55386 3.37993C9.62634 3.41563 10.103 4.16533 9.48334 4.96264L8.41086 6.33114L8.45852 6.35494C10.6512 7.80675 13.3324 10.8294 13.9759 12.8286H14.0235C14.6551 10.8413 17.3482 7.80675 19.5409 6.35494L19.6004 6.31924L18.5041 4.80794C17.9083 3.98683 18.3969 3.24903 19.4813 3.26093L24.8556 3.23713C25.7136 3.23713 26.1903 3.90353 25.9281 4.72464L24.2598 9.81786C23.938 10.8413 23.0801 11.115 22.4723 10.2701L21.3164 8.67545L21.0543 8.84205C18.659 10.3653 15.4416 14.1138 15.4416 16.8389V23.2054C15.4416 24.2407 14.9292 24.8 13.9997 24.8C13.0702 24.8 12.5697 24.2407 12.5697 23.2054V16.8389C12.5697 14.1138 9.32843 10.3653 6.94513 8.84205L6.62338 8.63975L5.32449 10.3058Z"),
)
}.build()
return _ic_arrow_split_top_28!!
}
@Composable
@Preview(showBackground = true)
private fun IcArrowSplitTop28Preview() {
Icon(
imageVector = Icons.ic_arrow_split_top_28,
contentDescription = null,
)
}

View file

@ -31,7 +31,7 @@ val Icons.ic_arrow_swap_horizontal_12: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M10 5.50004C10.2761 5.50009 10.5 5.72393 10.5 6.00004C10.4999 7.97667 9.03239 9.38859 7.11133 9.38871H3.14258C3.17968 9.41851 3.2133 9.44786 3.24512 9.47269C3.29449 9.51123 3.33569 9.54291 3.36426 9.56449C3.37832 9.57511 3.39012 9.58343 3.39746 9.5889C3.40102 9.59155 3.40356 9.59441 3.40527 9.59574L3.40723 9.59671C3.62953 9.76043 3.67729 10.0736 3.51367 10.2959C3.37035 10.4905 3.1125 10.5518 2.90137 10.4541L2.81445 10.4024L2.81348 10.4014C2.81281 10.4009 2.81152 10.4002 2.81055 10.3994C2.80809 10.3976 2.80409 10.3948 2.7998 10.3916C2.79087 10.385 2.77772 10.3744 2.76172 10.3623C2.72962 10.3381 2.68391 10.3039 2.62988 10.2618C2.52156 10.1772 2.37507 10.0598 2.22754 9.93168C2.08245 9.80569 1.92445 9.65881 1.79883 9.51664C1.73656 9.44615 1.67118 9.36467 1.61914 9.27836C1.58631 9.22384 1.53602 9.13061 1.5127 9.01371L1.5 8.88871L1.5127 8.76371C1.53605 8.64638 1.58629 8.55258 1.61914 8.49808C1.67121 8.41177 1.73656 8.33027 1.79883 8.2598C1.9244 8.11773 2.08255 7.97163 2.22754 7.84574C2.37514 7.71758 2.52154 7.60021 2.62988 7.51566C2.68422 7.47326 2.72956 7.43839 2.76172 7.4141C2.77779 7.40196 2.79087 7.39244 2.7998 7.38578C2.80426 7.38246 2.80807 7.3798 2.81055 7.37796C2.81169 7.37712 2.8128 7.37651 2.81348 7.37601L2.81445 7.37504C3.03666 7.21141 3.34984 7.25852 3.51367 7.4805C3.67742 7.70284 3.62955 8.01596 3.40723 8.17972C3.40688 8.17998 3.40612 8.18104 3.40527 8.18168C3.40356 8.18295 3.40093 8.18495 3.39746 8.18754C3.39013 8.193 3.37852 8.20117 3.36426 8.21195C3.33571 8.23351 3.29464 8.2651 3.24512 8.30375C3.21302 8.32879 3.1791 8.35858 3.1416 8.38871H7.11133C8.49051 8.38859 9.49991 7.41403 9.5 6.00004C9.5 5.72389 9.72386 5.50004 10 5.50004Z"),
pathData = addPathNodes("M10 5.50004C10.2761 5.50009 10.5 5.72393 10.5 6.00004C10.4999 7.97667 9.03239 9.38859 7.11133 9.38871H3.14258C3.17968 9.41851 3.2133 9.44786 3.24512 9.47269C3.29449 9.51123 3.33569 9.54291 3.36426 9.56449C3.37832 9.57511 3.39012 9.58343 3.39746 9.5889C3.40102 9.59155 3.40356 9.59441 3.40527 9.59574L3.40723 9.59671C3.62953 9.76043 3.67729 10.0736 3.51367 10.2959C3.37035 10.4905 3.1125 10.5518 2.90137 10.4541L2.81445 10.4024L2.81348 10.4014C2.81281 10.4009 2.81152 10.4002 2.81055 10.3994C2.80809 10.3976 2.80409 10.3948 2.7998 10.3916C2.79087 10.385 2.77772 10.3744 2.76172 10.3623C2.72962 10.3381 2.68391 10.3039 2.62988 10.2618C2.52156 10.1772 2.37507 10.0598 2.22754 9.93168C2.08245 9.80569 1.92445 9.65881 1.79883 9.51664C1.73656 9.44615 1.67118 9.36467 1.61914 9.27836C1.58631 9.22384 1.53602 9.13061 1.5127 9.01371L1.5 8.88871L1.5127 8.76371C1.53605 8.64638 1.58629 8.55258 1.61914 8.49808C1.67121 8.41177 1.73656 8.33027 1.79883 8.2598C1.9244 8.11773 2.08255 7.97163 2.22754 7.84574C2.37514 7.71758 2.52154 7.60021 2.62988 7.51566C2.68422 7.47326 2.72956 7.43839 2.76172 7.4141C2.77779 7.40196 2.79087 7.39243 2.7998 7.38578C2.80426 7.38246 2.80807 7.3798 2.81055 7.37796C2.81169 7.37712 2.8128 7.37651 2.81348 7.37601L2.81445 7.37504C3.03666 7.21141 3.34984 7.25852 3.51367 7.4805C3.67742 7.70284 3.62955 8.01596 3.40723 8.17972C3.40688 8.17998 3.40612 8.18104 3.40527 8.18168C3.40356 8.18295 3.40093 8.18495 3.39746 8.18754C3.39013 8.193 3.37852 8.20117 3.36426 8.21195C3.33571 8.23351 3.29464 8.2651 3.24512 8.30375C3.21302 8.32879 3.1791 8.35858 3.1416 8.38871H7.11133C8.49051 8.38859 9.49991 7.41403 9.5 6.00004C9.5 5.72389 9.72386 5.50004 10 5.50004Z"),
)
addPath(
fill = SolidColor(Color.Black),

View file

@ -31,12 +31,12 @@ val Icons.ic_arrow_swap_horizontal_20: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M16.7457 9.24631C17.1599 9.24631 17.4957 9.5821 17.4957 9.99631C17.4955 13.2795 15.062 15.6213 11.8707 15.6213H4.90485C5.04583 15.7382 5.17904 15.8456 5.28961 15.9319C5.37369 15.9975 5.44327 16.0515 5.49176 16.0881C5.51566 16.1062 5.53492 16.1198 5.54742 16.1291C5.55362 16.1337 5.55912 16.1377 5.56207 16.1399C5.56327 16.1407 5.56442 16.1414 5.565 16.1418L5.56598 16.1428C5.89901 16.3885 5.96968 16.8583 5.72418 17.1916C5.47861 17.5246 5.00968 17.5958 4.67633 17.3508L4.67535 17.3498L4.6734 17.3489C4.67228 17.348 4.67039 17.3463 4.66852 17.3449C4.66451 17.342 4.65894 17.3375 4.65192 17.3322C4.63702 17.3212 4.61532 17.3047 4.58844 17.2844C4.53459 17.2437 4.45795 17.1856 4.36676 17.1145C4.18473 16.9724 3.93841 16.7756 3.69098 16.5608C3.44733 16.3492 3.18409 16.1047 2.97614 15.8694C2.873 15.7526 2.76789 15.6196 2.68414 15.4807C2.61272 15.3622 2.4957 15.1417 2.49567 14.8713C2.49571 14.6008 2.61273 14.3804 2.68414 14.2619C2.76794 14.1229 2.87292 13.9901 2.97614 13.8733C3.18415 13.6378 3.44725 13.3935 3.69098 13.1819C3.9384 12.967 4.18374 12.7702 4.36578 12.6281C4.45719 12.5568 4.53449 12.499 4.58844 12.4582C4.61519 12.438 4.63606 12.4215 4.65094 12.4104C4.65824 12.4049 4.66442 12.4007 4.66852 12.3977C4.67051 12.3962 4.67224 12.3946 4.6734 12.3938L4.67535 12.3928C5.00886 12.1473 5.47858 12.2185 5.72418 12.552C5.96945 12.8853 5.89892 13.3541 5.56598 13.5998L5.565 13.6008C5.56442 13.6012 5.56335 13.6018 5.56207 13.6028C5.5591 13.605 5.55367 13.6088 5.54742 13.6135C5.5349 13.6228 5.51578 13.6373 5.49176 13.6555C5.44329 13.6921 5.37349 13.7453 5.28961 13.8108C5.17903 13.8971 5.04588 14.0043 4.90485 14.1213H11.8707C14.2491 14.1213 15.9955 12.4356 15.9957 9.99631C15.9957 9.58211 16.3315 9.24633 16.7457 9.24631Z"),
pathData = addPathNodes("M16.7457 9.24631C17.1599 9.24631 17.4957 9.5821 17.4957 9.99631C17.4955 13.2795 15.062 15.6213 11.8707 15.6213H4.90485C5.04583 15.7382 5.17904 15.8456 5.28961 15.9319C5.37369 15.9975 5.44327 16.0515 5.49176 16.0881C5.51566 16.1062 5.53492 16.1198 5.54742 16.1291C5.55362 16.1337 5.55912 16.1377 5.56207 16.1399C5.56327 16.1407 5.56442 16.1414 5.565 16.1418L5.56598 16.1428C5.89901 16.3886 5.96968 16.8583 5.72418 17.1916C5.47861 17.5246 5.00968 17.5958 4.67633 17.3508L4.67535 17.3498L4.6734 17.3489C4.67228 17.348 4.67039 17.3463 4.66852 17.3449C4.66451 17.342 4.65894 17.3375 4.65192 17.3322C4.63702 17.3212 4.61532 17.3047 4.58844 17.2844C4.53459 17.2437 4.45795 17.1856 4.36676 17.1145C4.18473 16.9724 3.93841 16.7756 3.69098 16.5608C3.44733 16.3492 3.18409 16.1047 2.97614 15.8694C2.873 15.7526 2.76789 15.6196 2.68414 15.4807C2.61272 15.3622 2.4957 15.1417 2.49567 14.8713C2.49571 14.6008 2.61273 14.3804 2.68414 14.2619C2.76794 14.1229 2.87292 13.9901 2.97614 13.8733C3.18415 13.6378 3.44725 13.3935 3.69098 13.1819C3.9384 12.967 4.18374 12.7702 4.36578 12.6281C4.45719 12.5568 4.53449 12.499 4.58844 12.4582C4.61519 12.438 4.63606 12.4215 4.65094 12.4104C4.65824 12.4049 4.66442 12.4007 4.66852 12.3977C4.67051 12.3962 4.67224 12.3946 4.6734 12.3938L4.67535 12.3928C5.00886 12.1473 5.47858 12.2185 5.72418 12.552C5.96945 12.8853 5.89892 13.3541 5.56598 13.5998L5.565 13.6008C5.56443 13.6012 5.56335 13.6018 5.56207 13.6028C5.5591 13.605 5.55367 13.6088 5.54742 13.6135C5.5349 13.6228 5.51578 13.6373 5.49176 13.6555C5.44329 13.6921 5.37349 13.7453 5.28961 13.8108C5.17903 13.8971 5.04588 14.0043 4.90485 14.1213H11.8707C14.2491 14.1213 15.9955 12.4356 15.9957 9.99631C15.9957 9.58211 16.3315 9.24633 16.7457 9.24631Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M14.2672 2.801C14.5128 2.4677 14.9816 2.39643 15.315 2.64182L15.3179 2.6428C15.3191 2.64365 15.3208 2.64523 15.3228 2.6467C15.3269 2.64973 15.3331 2.65398 15.3404 2.6594C15.3553 2.67048 15.3762 2.68707 15.4029 2.70725C15.4568 2.74799 15.5342 2.80586 15.6255 2.87717C15.8076 3.01924 16.053 3.21607 16.3004 3.43088C16.544 3.64248 16.8072 3.88689 17.0152 4.12229C17.1184 4.23907 17.2234 4.37202 17.3072 4.51096C17.3786 4.62939 17.4956 4.84988 17.4957 5.12034C17.4957 5.39069 17.3786 5.61114 17.3072 5.72971C17.2235 5.86861 17.1183 6.00161 17.0152 6.11838C16.8072 6.35374 16.544 6.59821 16.3004 6.80979C16.053 7.02454 15.8076 7.22143 15.6255 7.3635C15.5342 7.4348 15.4568 7.49267 15.4029 7.53342C15.3762 7.55358 15.3553 7.57016 15.3404 7.58127C15.3332 7.58663 15.3269 7.59094 15.3228 7.59397C15.3209 7.59536 15.3191 7.597 15.3179 7.59787L15.316 7.59885L15.315 7.59983C14.9816 7.84497 14.5128 7.77369 14.2672 7.44065C14.0218 7.10728 14.0922 6.6375 14.4254 6.39182L14.4263 6.39084C14.4269 6.39041 14.4281 6.38978 14.4293 6.38889C14.4323 6.38667 14.4377 6.38276 14.4439 6.37815C14.4564 6.36881 14.4757 6.35519 14.4996 6.33713C14.5481 6.30049 14.6176 6.24651 14.7017 6.18088C14.8123 6.09455 14.9454 5.98732 15.0865 5.87034H8.12067C5.74237 5.87037 3.99599 7.55626 3.99567 9.99534C3.99567 10.4095 3.6598 10.7452 3.24567 10.7453C2.83145 10.7453 2.49567 10.4095 2.49567 9.99534C2.496 6.71236 4.92948 4.37037 8.12067 4.37034H15.0865C14.9458 4.25344 14.8132 4.14602 14.7027 4.05979C14.6187 3.9942 14.5481 3.94119 14.4996 3.90452C14.4756 3.88639 14.4564 3.87185 14.4439 3.86252C14.4377 3.85789 14.4322 3.85397 14.4293 3.85178C14.428 3.85087 14.4269 3.85024 14.4263 3.84983L14.4254 3.84885C14.0924 3.60311 14.0218 3.13429 14.2672 2.801Z"),
pathData = addPathNodes("M14.2672 2.801C14.5128 2.4677 14.9816 2.39643 15.315 2.64182L15.3179 2.6428C15.3191 2.64365 15.3208 2.64523 15.3228 2.6467C15.3269 2.64973 15.3331 2.65398 15.3404 2.6594C15.3553 2.67048 15.3762 2.68707 15.4029 2.70725C15.4568 2.74799 15.5342 2.80586 15.6255 2.87717C15.8076 3.01924 16.053 3.21607 16.3004 3.43088C16.544 3.64248 16.8072 3.88689 17.0152 4.12229C17.1184 4.23907 17.2234 4.37202 17.3072 4.51096C17.3786 4.62939 17.4956 4.84988 17.4957 5.12034C17.4957 5.39069 17.3786 5.61114 17.3072 5.72971C17.2235 5.86861 17.1183 6.00161 17.0152 6.11838C16.8072 6.35374 16.544 6.5982 16.3004 6.80979C16.053 7.02454 15.8076 7.22143 15.6255 7.3635C15.5342 7.4348 15.4568 7.49267 15.4029 7.53342C15.3762 7.55358 15.3553 7.57016 15.3404 7.58127C15.3332 7.58663 15.3269 7.59094 15.3228 7.59397C15.3209 7.59536 15.3191 7.597 15.3179 7.59787L15.316 7.59885L15.315 7.59983C14.9816 7.84497 14.5128 7.77369 14.2672 7.44065C14.0218 7.10728 14.0922 6.6375 14.4254 6.39182L14.4263 6.39084C14.4269 6.39041 14.4281 6.38978 14.4293 6.38889C14.4323 6.38667 14.4377 6.38276 14.4439 6.37815C14.4564 6.36881 14.4757 6.35519 14.4996 6.33713C14.5481 6.30049 14.6176 6.24651 14.7017 6.18088C14.8123 6.09455 14.9454 5.98732 15.0865 5.87034H8.12067C5.74237 5.87037 3.99599 7.55626 3.99567 9.99534C3.99567 10.4095 3.6598 10.7452 3.24567 10.7453C2.83145 10.7453 2.49567 10.4095 2.49567 9.99534C2.496 6.71236 4.92948 4.37037 8.12067 4.37034H15.0865C14.9458 4.25344 14.8132 4.14602 14.7027 4.05979C14.6187 3.9942 14.5481 3.94119 14.4996 3.90452C14.4756 3.88639 14.4564 3.87185 14.4439 3.86252C14.4377 3.85789 14.4322 3.85397 14.4293 3.85178C14.428 3.85087 14.4269 3.85024 14.4263 3.84983L14.4254 3.84885C14.0924 3.60311 14.0218 3.13429 14.2672 2.801Z"),
)
}.build()
return _ic_arrow_swap_horizontal_20!!

View file

@ -31,12 +31,12 @@ val Icons.ic_arrow_swap_horizontal_24: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M20.4955 10.9976C21.0478 10.9976 21.4955 11.4453 21.4955 11.9976C21.4953 16.1623 18.4059 19.1351 14.3578 19.1353H5.74261C5.87496 19.243 5.99883 19.3418 6.1059 19.4253C6.21181 19.5079 6.29979 19.5755 6.36078 19.6216C6.39118 19.6446 6.4154 19.6617 6.43109 19.6734C6.43892 19.6792 6.44496 19.6843 6.44867 19.687L6.45258 19.69C6.89726 20.0173 6.99272 20.6437 6.66547 21.0884C6.35855 21.5052 5.78936 21.6145 5.35297 21.3569L5.26703 21.3003L5.2641 21.2984C5.26268 21.2973 5.26057 21.2962 5.25824 21.2944C5.25301 21.2906 5.24522 21.2849 5.23578 21.2778C5.21688 21.2638 5.18975 21.243 5.1557 21.2173C5.08762 21.1659 4.99152 21.0923 4.8764 21.0025C4.64664 20.8232 4.33651 20.5746 4.02386 20.3032C3.71627 20.0363 3.38294 19.7273 3.11859 19.4282C2.98742 19.2798 2.85158 19.1102 2.74359 18.9312C2.65214 18.7795 2.49847 18.4906 2.49847 18.1343C2.49865 17.7783 2.65219 17.49 2.74359 17.3384C2.85158 17.1594 2.98745 16.9897 3.11859 16.8413C3.38296 16.5423 3.71627 16.2323 4.02386 15.9653C4.33618 15.6943 4.64582 15.4462 4.87543 15.2671C4.99055 15.1773 5.0876 15.1037 5.1557 15.0523C5.18962 15.0266 5.21692 15.0058 5.23578 14.9917C5.24515 14.9847 5.25305 14.979 5.25824 14.9751C5.2605 14.9735 5.2627 14.9722 5.2641 14.9712L5.26605 14.9692C5.26892 14.973 5.30307 15.0175 5.6889 15.5415L5.26703 14.9683C5.71173 14.6411 6.33809 14.7366 6.66547 15.1812C6.99271 15.6258 6.89711 16.2522 6.45258 16.5796L6.44867 16.5825C6.44503 16.5852 6.43871 16.5896 6.43109 16.5952C6.41543 16.6069 6.39116 16.625 6.36078 16.648C6.29983 16.694 6.21167 16.7617 6.1059 16.8442C5.99844 16.9281 5.87356 17.027 5.74066 17.1353H14.3578C17.3221 17.1351 19.4953 15.0369 19.4955 11.9976C19.4955 11.4454 19.9434 10.9977 20.4955 10.9976Z"),
pathData = addPathNodes("M20.4955 10.9976C21.0478 10.9976 21.4955 11.4453 21.4955 11.9976C21.4953 16.1623 18.4059 19.1351 14.3578 19.1353H5.74261C5.87496 19.243 5.99883 19.3418 6.1059 19.4253C6.21181 19.5079 6.29979 19.5755 6.36078 19.6216C6.39118 19.6445 6.4154 19.6617 6.43109 19.6734C6.43892 19.6792 6.44496 19.6843 6.44867 19.687L6.45258 19.69C6.89726 20.0173 6.99272 20.6436 6.66547 21.0884C6.35855 21.5052 5.78936 21.6145 5.35297 21.3569L5.26703 21.3003L5.2641 21.2984C5.26268 21.2973 5.26057 21.2962 5.25824 21.2944C5.25301 21.2906 5.24522 21.2849 5.23578 21.2778C5.21688 21.2638 5.18975 21.243 5.1557 21.2173C5.08762 21.1659 4.99152 21.0923 4.8764 21.0025C4.64664 20.8232 4.33651 20.5746 4.02386 20.3032C3.71627 20.0363 3.38294 19.7273 3.11859 19.4282C2.98742 19.2798 2.85158 19.1102 2.74359 18.9312C2.65214 18.7795 2.49847 18.4906 2.49847 18.1343C2.49865 17.7783 2.65219 17.49 2.74359 17.3384C2.85158 17.1594 2.98745 16.9897 3.11859 16.8413C3.38296 16.5423 3.71627 16.2323 4.02386 15.9653C4.33618 15.6943 4.64582 15.4462 4.87543 15.2671C4.99055 15.1773 5.0876 15.1037 5.1557 15.0523C5.18962 15.0266 5.21692 15.0058 5.23578 14.9917C5.24515 14.9847 5.25305 14.979 5.25824 14.9751C5.2605 14.9735 5.2627 14.9722 5.2641 14.9712L5.26605 14.9692C5.26892 14.973 5.30307 15.0175 5.6889 15.5415L5.26703 14.9683C5.71173 14.6411 6.33809 14.7366 6.66547 15.1812C6.99272 15.6258 6.89711 16.2522 6.45258 16.5796L6.44867 16.5825C6.44503 16.5852 6.43872 16.5896 6.43109 16.5952C6.41543 16.6069 6.39116 16.625 6.36078 16.648C6.29983 16.694 6.21167 16.7617 6.1059 16.8442C5.99844 16.9281 5.87356 17.027 5.74066 17.1353H14.3578C17.3221 17.1351 19.4953 15.0369 19.4955 11.9976C19.4955 11.4454 19.9434 10.9977 20.4955 10.9976Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M17.3295 2.90577C17.6569 2.46114 18.2832 2.36568 18.728 2.69288L18.7309 2.69581C18.7323 2.69683 18.7345 2.69804 18.7368 2.69972C18.742 2.70359 18.7498 2.70934 18.7592 2.71632C18.7781 2.7304 18.8053 2.75119 18.8393 2.77687C18.9074 2.82832 19.0044 2.90184 19.1196 2.99171C19.3492 3.17086 19.6588 3.41888 19.9711 3.68995C20.2788 3.95699 20.613 4.26683 20.8774 4.56593C21.0085 4.71425 21.1435 4.88407 21.2514 5.063C21.3428 5.21463 21.4964 5.50286 21.4965 5.8589C21.4965 6.21521 21.3428 6.50414 21.2514 6.65577C21.1435 6.83475 21.0085 7.0045 20.8774 7.15284C20.613 7.45197 20.2788 7.7608 19.9711 8.02784C19.6586 8.29911 19.3493 8.54784 19.1196 8.72706C19.0043 8.81701 18.9074 8.89045 18.8393 8.94191C18.8052 8.96763 18.7781 8.98837 18.7592 9.00245C18.7498 9.00944 18.742 9.0152 18.7368 9.01905C18.7344 9.02077 18.7323 9.02193 18.7309 9.02296L18.7289 9.02491C18.2842 9.35232 17.657 9.25765 17.3295 8.813C17.0022 8.36825 17.0977 7.74198 17.5424 7.41456C17.5432 7.41398 17.5456 7.4129 17.5473 7.41163C17.551 7.40888 17.5562 7.40369 17.5639 7.39796C17.5796 7.38628 17.6038 7.36916 17.6342 7.3462C17.6952 7.30015 17.7832 7.23256 17.8891 7.14991C17.9966 7.06604 18.1214 6.96718 18.2543 6.8589H9.63617C6.67185 6.85903 4.49868 8.95717 4.49847 11.9966C4.49847 12.5488 4.0507 12.9965 3.49847 12.9966C2.94619 12.9966 2.49847 12.5489 2.49847 11.9966C2.49869 7.83185 5.58813 4.85903 9.63617 4.8589H18.2524C18.12 4.75115 17.9962 4.65239 17.8891 4.56886C17.7833 4.48628 17.6952 4.41862 17.6342 4.37257C17.6038 4.34963 17.5796 4.33153 17.5639 4.31984C17.5565 4.31433 17.551 4.30986 17.5473 4.30714C17.5457 4.30597 17.5442 4.30482 17.5434 4.30421C17.0987 3.97683 17.0023 3.3505 17.3295 2.90577Z"),
pathData = addPathNodes("M17.3295 2.90577C17.6569 2.46114 18.2832 2.36568 18.728 2.69288L18.7309 2.69581C18.7323 2.69683 18.7345 2.69804 18.7368 2.69972C18.742 2.70359 18.7498 2.70934 18.7592 2.71632C18.7781 2.7304 18.8053 2.75119 18.8393 2.77687C18.9074 2.82832 19.0044 2.90184 19.1196 2.99171C19.3492 3.17086 19.6588 3.41888 19.9711 3.68995C20.2788 3.95699 20.613 4.26683 20.8774 4.56593C21.0085 4.71425 21.1435 4.88407 21.2514 5.063C21.3428 5.21463 21.4964 5.50286 21.4965 5.8589C21.4965 6.21521 21.3428 6.50414 21.2514 6.65577C21.1435 6.83475 21.0085 7.0045 20.8774 7.15284C20.613 7.45197 20.2788 7.7608 19.9711 8.02784C19.6586 8.29911 19.3493 8.54784 19.1196 8.72706C19.0043 8.81701 18.9074 8.89045 18.8393 8.94191C18.8052 8.96762 18.7781 8.98837 18.7592 9.00245C18.7498 9.00944 18.742 9.0152 18.7368 9.01905C18.7344 9.02077 18.7323 9.02193 18.7309 9.02296L18.7289 9.02491C18.2842 9.35232 17.657 9.25765 17.3295 8.813C17.0022 8.36825 17.0977 7.74198 17.5424 7.41456C17.5432 7.41398 17.5456 7.4129 17.5473 7.41163C17.551 7.40888 17.5562 7.40369 17.5639 7.39796C17.5796 7.38628 17.6038 7.36916 17.6342 7.3462C17.6952 7.30015 17.7832 7.23256 17.8891 7.14991C17.9966 7.06604 18.1214 6.96718 18.2543 6.8589H9.63617C6.67185 6.85903 4.49868 8.95717 4.49847 11.9966C4.49847 12.5488 4.0507 12.9965 3.49847 12.9966C2.94619 12.9966 2.49847 12.5489 2.49847 11.9966C2.49869 7.83185 5.58813 4.85903 9.63617 4.8589H18.2524C18.12 4.75115 17.9962 4.65239 17.8891 4.56886C17.7833 4.48628 17.6952 4.41862 17.6342 4.37257C17.6038 4.34963 17.5796 4.33153 17.5639 4.31984C17.5565 4.31433 17.551 4.30986 17.5473 4.30714C17.5457 4.30597 17.5442 4.30482 17.5434 4.30421C17.0987 3.97683 17.0023 3.3505 17.3295 2.90577Z"),
)
}.build()
return _ic_arrow_swap_horizontal_24!!

View file

@ -31,12 +31,12 @@ val Icons.ic_arrow_swap_horizontal_28: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M24.2441 12.7517C24.9345 12.7517 25.4941 13.3113 25.4941 14.0017C25.4939 19.0495 21.7491 22.6547 16.8438 22.655H6.5791C6.70293 22.7548 6.81889 22.8471 6.92188 22.9274C7.04931 23.0269 7.1552 23.1084 7.22852 23.1638C7.26498 23.1913 7.29372 23.2123 7.3125 23.2263C7.32174 23.2332 7.32859 23.2386 7.33301 23.2419C7.33517 23.2435 7.337 23.2451 7.33789 23.2458C7.89346 23.6552 8.01271 24.4381 7.60352 24.9938C7.21978 25.5147 6.50827 25.6517 5.96289 25.3298L5.85547 25.2585C5.85495 25.2581 5.85333 25.2572 5.85254 25.2565C5.85073 25.2552 5.84784 25.253 5.84473 25.2507C5.83846 25.246 5.82952 25.2395 5.81836 25.2311C5.79552 25.2141 5.76282 25.189 5.72168 25.1579C5.63937 25.0957 5.52211 25.0069 5.38281 24.8981C5.10561 24.6818 4.73184 24.382 4.35449 24.0544C3.983 23.7318 3.57848 23.3568 3.25781 22.9938C3.09888 22.8139 2.93379 22.6074 2.80176 22.3884C2.70422 22.2266 2.54669 21.933 2.50879 21.5661L2.5 21.405L2.50879 21.2438C2.54669 20.877 2.70422 20.5834 2.80176 20.4216C2.93376 20.2026 3.09891 19.996 3.25781 19.8161C3.57843 19.4532 3.98209 19.0781 4.35352 18.7556C4.73097 18.4278 5.10552 18.1283 5.38281 17.9118C5.52208 17.8031 5.63939 17.7132 5.72168 17.6511C5.76258 17.6202 5.79561 17.5958 5.81836 17.5788C5.82947 17.5705 5.83847 17.5639 5.84473 17.5593C5.84781 17.557 5.85075 17.5547 5.85254 17.5534L5.85547 17.5505C6.4113 17.1412 7.19414 17.2603 7.60352 17.8161C8.0128 18.3719 7.89351 19.1537 7.33789 19.5632C7.33701 19.5638 7.33513 19.5665 7.33301 19.5681C7.32859 19.5713 7.32167 19.5768 7.3125 19.5837C7.29372 19.5977 7.26496 19.6187 7.22852 19.6462C7.1552 19.7016 7.0493 19.7831 6.92188 19.8825C6.81891 19.9629 6.70289 20.0552 6.5791 20.155H16.8438C20.3935 20.1548 22.994 17.6438 22.9941 14.0017C22.9941 13.3114 23.5539 12.7518 24.2441 12.7517Z"),
pathData = addPathNodes("M24.2441 12.7517C24.9345 12.7517 25.4941 13.3113 25.4941 14.0017C25.4939 19.0495 21.7491 22.6547 16.8438 22.655H6.5791C6.70293 22.7548 6.81889 22.8471 6.92188 22.9274C7.04931 23.0269 7.1552 23.1084 7.22852 23.1638C7.26498 23.1913 7.29372 23.2123 7.3125 23.2263C7.32174 23.2332 7.32859 23.2386 7.33301 23.2419C7.33517 23.2435 7.337 23.2451 7.33789 23.2458C7.89346 23.6552 8.01271 24.4381 7.60352 24.9938C7.21978 25.5147 6.50827 25.6517 5.96289 25.3298L5.85547 25.2585C5.85495 25.2581 5.85333 25.2572 5.85254 25.2565C5.85073 25.2552 5.84784 25.253 5.84473 25.2507C5.83846 25.246 5.82952 25.2395 5.81836 25.2311C5.79552 25.2141 5.76282 25.189 5.72168 25.1579C5.63937 25.0957 5.52211 25.0069 5.38281 24.8981C5.10561 24.6818 4.73184 24.382 4.35449 24.0544C3.983 23.7318 3.57848 23.3568 3.25781 22.9938C3.09888 22.8139 2.93379 22.6074 2.80176 22.3884C2.70422 22.2266 2.54669 21.933 2.50879 21.5661L2.5 21.405L2.50879 21.2438C2.54669 20.877 2.70422 20.5834 2.80176 20.4216C2.93376 20.2026 3.09891 19.996 3.25781 19.8161C3.57843 19.4532 3.98209 19.0781 4.35352 18.7556C4.73097 18.4278 5.10552 18.1283 5.38281 17.9118C5.52208 17.8031 5.63939 17.7132 5.72168 17.6511C5.76259 17.6202 5.79561 17.5958 5.81836 17.5788C5.82947 17.5705 5.83847 17.5639 5.84473 17.5593C5.84781 17.557 5.85075 17.5547 5.85254 17.5534L5.85547 17.5505C6.4113 17.1412 7.19414 17.2603 7.60352 17.8161C8.0128 18.3719 7.89351 19.1537 7.33789 19.5632C7.33701 19.5638 7.33513 19.5665 7.33301 19.5681C7.32859 19.5713 7.32167 19.5768 7.3125 19.5837C7.29372 19.5977 7.26496 19.6187 7.22852 19.6462C7.1552 19.7016 7.0493 19.7831 6.92188 19.8825C6.81891 19.9629 6.70289 20.0552 6.5791 20.155H16.8438C20.3935 20.1548 22.994 17.6438 22.9941 14.0017C22.9941 13.3114 23.5539 12.7518 24.2441 12.7517Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M20.3916 3.00849C20.801 2.45311 21.584 2.33379 22.1396 2.74287L22.1406 2.74385C22.1413 2.7443 22.1427 2.74518 22.1436 2.7458C22.1453 2.74714 22.1475 2.74949 22.1504 2.75166C22.1567 2.75634 22.1664 2.76274 22.1777 2.77119C22.2006 2.7882 22.2335 2.81251 22.2744 2.84345C22.3567 2.90564 22.473 2.99549 22.6123 3.1042C22.8896 3.32065 23.2641 3.62011 23.6416 3.94795C24.0131 4.27054 24.4167 4.64555 24.7373 5.00849C24.8962 5.18841 25.0613 5.39498 25.1934 5.61396C25.3048 5.7988 25.496 6.15564 25.4961 6.59736C25.4961 7.03887 25.3048 7.39576 25.1934 7.58076C25.0614 7.79961 24.8962 8.00639 24.7373 8.18623C24.4167 8.54907 24.013 8.92424 23.6416 9.24678C23.2642 9.57449 22.8896 9.8741 22.6123 10.0905C22.4734 10.199 22.3567 10.2881 22.2744 10.3503C22.2335 10.3812 22.2006 10.4065 22.1777 10.4235C22.1666 10.4319 22.1567 10.4384 22.1504 10.4431C22.1476 10.4451 22.1452 10.4476 22.1436 10.4489L22.1406 10.4509C21.5848 10.8603 20.801 10.7421 20.3916 10.1862C19.9823 9.63039 20.1014 8.84757 20.6572 8.43818C20.658 8.43737 20.6604 8.43556 20.6621 8.43428C20.6666 8.43097 20.6745 8.42544 20.6836 8.41865C20.7024 8.4046 20.7314 8.38351 20.7676 8.35615C20.8409 8.30073 20.9469 8.21918 21.0742 8.11982C21.1771 8.03952 21.2924 7.94701 21.416 7.84736H11.1504C7.60071 7.84759 5.00029 10.3587 5 14.0007C5 14.6909 4.44024 15.2505 3.75 15.2507C3.05964 15.2507 2.5 14.691 2.5 14.0007C2.5003 8.95295 6.24511 5.34759 11.1504 5.34736H21.416C21.2924 5.24771 21.1771 5.15519 21.0742 5.0749C20.9468 4.97544 20.8409 4.894 20.7676 4.83857C20.7312 4.81111 20.7024 4.79012 20.6836 4.77607C20.6743 4.76913 20.6666 4.76374 20.6621 4.76045C20.6602 4.75903 20.6591 4.75727 20.6582 4.75654C20.1025 4.34718 19.9824 3.56432 20.3916 3.00849Z"),
pathData = addPathNodes("M20.3916 3.00849C20.801 2.45311 21.584 2.33379 22.1396 2.74287L22.1406 2.74385C22.1413 2.7443 22.1427 2.74518 22.1436 2.7458C22.1453 2.74714 22.1475 2.74949 22.1504 2.75166C22.1567 2.75634 22.1664 2.76274 22.1777 2.77119C22.2006 2.7882 22.2335 2.81251 22.2744 2.84345C22.3567 2.90564 22.473 2.99549 22.6123 3.1042C22.8896 3.32065 23.2641 3.62011 23.6416 3.94795C24.0131 4.27054 24.4167 4.64555 24.7373 5.00849C24.8962 5.18841 25.0613 5.39498 25.1934 5.61396C25.3048 5.7988 25.496 6.15564 25.4961 6.59736C25.4961 7.03887 25.3048 7.39576 25.1934 7.58076C25.0614 7.79961 24.8962 8.00639 24.7373 8.18623C24.4167 8.54907 24.013 8.92424 23.6416 9.24678C23.2642 9.57449 22.8896 9.8741 22.6123 10.0905C22.4734 10.199 22.3567 10.2881 22.2744 10.3503C22.2335 10.3812 22.2006 10.4065 22.1777 10.4235C22.1666 10.4319 22.1567 10.4384 22.1504 10.4431C22.1476 10.4451 22.1452 10.4476 22.1436 10.4489L22.1406 10.4509C21.5848 10.8603 20.801 10.7421 20.3916 10.1862C19.9823 9.63039 20.1014 8.84756 20.6572 8.43818C20.658 8.43737 20.6604 8.43556 20.6621 8.43428C20.6666 8.43097 20.6745 8.42544 20.6836 8.41865C20.7024 8.4046 20.7314 8.38351 20.7676 8.35615C20.8409 8.30073 20.9469 8.21918 21.0742 8.11982C21.1771 8.03952 21.2924 7.94701 21.416 7.84736H11.1504C7.60071 7.84759 5.00029 10.3587 5 14.0007C5 14.6909 4.44024 15.2505 3.75 15.2507C3.05964 15.2507 2.5 14.691 2.5 14.0007C2.5003 8.95295 6.24511 5.34759 11.1504 5.34736H21.416C21.2924 5.24771 21.1771 5.15519 21.0742 5.0749C20.9468 4.97544 20.8409 4.894 20.7676 4.83857C20.7312 4.81111 20.7024 4.79012 20.6836 4.77607C20.6743 4.76913 20.6666 4.76374 20.6621 4.76045C20.6602 4.75903 20.6591 4.75727 20.6582 4.75654C20.1025 4.34718 19.9824 3.56432 20.3916 3.00849Z"),
)
}.build()
return _ic_arrow_swap_horizontal_28!!

View file

@ -31,7 +31,7 @@ val Icons.ic_arrow_up_24: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M19.7048 9.29199C20.0948 9.68237 20.0947 10.3156 19.7048 10.7061C19.3144 11.0963 18.6813 11.0961 18.2908 10.7061L12.9988 5.41406L12.9988 20.999C12.9986 21.5509 12.5506 21.9986 11.9988 21.999C11.4466 21.999 10.9989 21.5512 10.9988 20.999L10.9988 5.41406L5.70679 10.7061C5.31639 11.0963 4.68324 11.0961 4.29272 10.7061C3.9024 10.3156 3.90237 9.68248 4.29272 9.29199L11.2917 2.29297C11.4792 2.10579 11.7338 2.00001 11.9988 2C12.2637 2.00021 12.5185 2.1057 12.7058 2.29297L19.7048 9.29199Z"),
pathData = addPathNodes("M19.7048 9.29199C20.0948 9.68237 20.0947 10.3156 19.7048 10.7061C19.3144 11.0963 18.6813 11.0961 18.2908 10.7061L12.9988 5.41406L12.9988 20.999C12.9986 21.5509 12.5506 21.9986 11.9988 21.999C11.4466 21.999 10.9989 21.5512 10.9988 20.999L10.9988 5.41406L5.70679 10.7061C5.31639 11.0963 4.68324 11.0961 4.29272 10.7061C3.9024 10.3156 3.90237 9.68247 4.29272 9.29199L11.2917 2.29297C11.4792 2.10579 11.7338 2.00001 11.9988 2C12.2637 2.00021 12.5185 2.1057 12.7058 2.29297L19.7048 9.29199Z"),
)
}.build()
return _ic_arrow_up_24!!

View file

@ -31,7 +31,7 @@ val Icons.ic_arrow_up_32: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M14.5003 27.3333C14.5003 28.1617 15.1719 28.8333 16.0003 28.8333C16.8286 28.8331 17.5003 28.1616 17.5003 27.3333V8.95538L25.6058 17.0609C26.1915 17.6465 27.1411 17.6463 27.7269 17.0609C28.3127 16.4751 28.3127 15.5255 27.7269 14.9398L17.0609 4.27277C16.4752 3.68703 15.5256 3.68714 14.9398 4.27277L4.2728 14.9398C3.68717 15.5256 3.68706 16.4751 4.2728 17.0609C4.85854 17.6464 5.80815 17.6464 6.39389 17.0609L14.5003 8.95441V27.3333Z"),
pathData = addPathNodes("M14.5003 27.3333C14.5003 28.1617 15.1719 28.8333 16.0003 28.8333C16.8286 28.8331 17.5003 28.1616 17.5003 27.3333V8.95538L25.6058 17.0609C26.1915 17.6465 27.1411 17.6463 27.7269 17.0609C28.3127 16.4751 28.3127 15.5255 27.7269 14.9398L17.0609 4.27277C16.4751 3.68703 15.5256 3.68714 14.9398 4.27277L4.2728 14.9398C3.68717 15.5256 3.68706 16.4751 4.2728 17.0609C4.85854 17.6464 5.80815 17.6464 6.39389 17.0609L14.5003 8.95441V27.3333Z"),
)
}.build()
return _ic_arrow_up_32!!

View file

@ -0,0 +1,52 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_bell_cross_20: ImageVector? = null
val Icons.ic_bell_cross_20: ImageVector
get() {
if (_ic_bell_cross_20 != null) return _ic_bell_cross_20!!
_ic_bell_cross_20 = ImageVector.Builder(
name = "ic_bell_cross_20",
defaultWidth = 20.dp,
defaultHeight = 20.dp,
viewportWidth = 20f,
viewportHeight = 20f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M3.07252 3.07764C3.3653 2.7851 3.8402 2.78508 4.13306 3.07764L16.928 15.8608C17.2208 16.1535 17.2204 16.6284 16.928 16.9214C16.6353 17.2144 16.1605 17.215 15.8674 16.9224L14.5276 15.5835H12.7385C12.6635 16.1894 12.3897 16.7577 11.9534 17.1938C11.4365 17.71 10.7346 17.9995 10.0042 17.9995C9.27332 17.9999 8.57114 17.7112 8.05396 17.1948C7.6172 16.7586 7.34477 16.1898 7.26978 15.5835H5.21021C4.57276 15.5835 3.96104 15.3298 3.51002 14.8794C3.05901 14.4287 2.80504 13.8168 2.80494 13.1792L2.81763 12.9321C2.87484 12.3604 3.12781 11.8228 3.53736 11.4126L4.41724 10.5317V5.48096L3.07252 4.13818C2.77978 3.8454 2.77985 3.37056 3.07252 3.07764ZM8.7942 15.5835C8.85191 15.7893 8.96061 15.9796 9.11451 16.1333C9.35005 16.3683 9.67009 16.5006 10.0032 16.5005C10.3363 16.5005 10.6573 16.3674 10.8928 16.1323C11.0464 15.9787 11.1564 15.7888 11.2141 15.5835H8.7942ZM5.91724 10.8442C5.91712 11.0428 5.83784 11.234 5.69752 11.3745L4.59791 12.4731L4.59693 12.4722C4.40976 12.66 4.30524 12.9153 4.30494 13.1802C4.3052 13.4194 4.40015 13.6495 4.56959 13.8188C4.73924 13.9882 4.97019 14.0835 5.21021 14.0835H13.0266L5.91724 6.97998V10.8442Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M10.0032 2.00049C13.0883 2.00049 15.5901 4.50026 15.5901 7.58447V10.5679C15.5896 10.9817 15.254 11.3179 14.8401 11.3179C14.4263 11.3177 14.0906 10.9816 14.0901 10.5679V7.58447C14.0901 5.32968 12.2608 3.50049 10.0032 3.50049C9.23136 3.50055 8.51118 3.71344 7.89674 4.0835C7.54213 4.29673 7.08118 4.18291 6.86744 3.82861C6.65381 3.47391 6.76877 3.01214 7.1233 2.79834C7.96477 2.29163 8.95129 2.00055 10.0032 2.00049Z"),
)
}.build()
return _ic_bell_cross_20!!
}
@Composable
@Preview(showBackground = true)
private fun IcBellCross20Preview() {
Icon(
imageVector = Icons.ic_bell_cross_20,
contentDescription = null,
)
}

View file

@ -0,0 +1,52 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_bell_cross_24: ImageVector? = null
val Icons.ic_bell_cross_24: ImageVector
get() {
if (_ic_bell_cross_24 != null) return _ic_bell_cross_24!!
_ic_bell_cross_24 = ImageVector.Builder(
name = "ic_bell_cross_24",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M3.39043 3.36182C3.78092 2.97139 4.41397 2.97138 4.80449 3.36182L20.6736 19.228C21.064 19.6185 21.0649 20.2516 20.6746 20.6421C20.2842 21.0326 19.6501 21.0324 19.2596 20.6421L17.616 18.9985H15.4871C15.3818 19.7438 15.0372 20.4399 14.4988 20.978C13.8443 21.6321 12.9563 21.9979 12.0311 21.9976C11.1064 21.9978 10.2185 21.6325 9.56425 20.979C9.02576 20.4408 8.68203 19.744 8.57695 18.9985H6.08574C5.27631 18.9985 4.5 18.6772 3.92754 18.105C3.35518 17.5326 3.03314 16.7562 3.033 15.9468L3.03691 15.7886C3.07633 15.0055 3.40441 14.2622 3.96074 13.7046L5.033 12.6323V6.41748L3.39043 4.77588C2.99994 4.38539 2.99997 3.75236 3.39043 3.36182ZM10.6268 18.9985C10.6999 19.2091 10.8178 19.4035 10.9783 19.564C11.2574 19.8426 11.6367 19.9987 12.0311 19.9985C12.4259 19.9986 12.8055 19.8421 13.0848 19.563C13.2453 19.4025 13.3641 19.2089 13.4373 18.9985H10.6268ZM7.033 13.0474C7.03298 13.3125 6.92743 13.5679 6.74004 13.7554L5.37578 15.1177C5.15655 15.3378 5.03343 15.6361 5.033 15.9468L5.03789 16.0503C5.06181 16.2912 5.16888 16.5182 5.3416 16.6909C5.53898 16.8881 5.80672 16.9985 6.08574 16.9985H15.615L7.033 8.41748V13.0474Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M12.032 2.00244C15.8974 2.00265 19.0311 5.1361 19.0311 9.00146V12.7046C19.0308 13.2566 18.5831 13.7045 18.0311 13.7046C17.479 13.7045 17.0313 13.2566 17.0311 12.7046V9.00146C17.0311 6.24078 14.793 4.00265 12.032 4.00244C11.0879 4.00246 10.2074 4.26346 9.45586 4.71631C8.98286 5.00129 8.36787 4.84845 8.08281 4.37549C7.79808 3.90267 7.95012 3.28856 8.42265 3.00342C9.4771 2.36794 10.7139 2.00246 12.032 2.00244Z"),
)
}.build()
return _ic_bell_cross_24!!
}
@Composable
@Preview(showBackground = true)
private fun IcBellCross24Preview() {
Icon(
imageVector = Icons.ic_bell_cross_24,
contentDescription = null,
)
}

View file

@ -0,0 +1,52 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_bell_cross_28: ImageVector? = null
val Icons.ic_bell_cross_28: ImageVector
get() {
if (_ic_bell_cross_28 != null) return _ic_bell_cross_28!!
_ic_bell_cross_28 = ImageVector.Builder(
name = "ic_bell_cross_28",
defaultWidth = 28.dp,
defaultHeight = 28.dp,
viewportWidth = 28f,
viewportHeight = 28f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M3.57854 3.5791C4.09908 3.05856 4.94276 3.05857 5.4633 3.5791L24.4223 22.5371C24.9421 23.0576 24.9423 23.9015 24.4223 24.4219C23.9019 24.9423 23.0571 24.9419 22.5365 24.4219L20.5317 22.417H18.1742C18.0391 23.3009 17.6258 24.1257 16.9858 24.7656C16.1935 25.5574 15.1186 26.0023 13.9985 26.002C12.8789 26.0023 11.8041 25.558 11.0121 24.7666C10.3718 24.1265 9.95867 23.3013 9.82366 22.417H6.89592C5.91413 22.4169 4.97199 22.0272 4.27776 21.333C3.58354 20.6386 3.19381 19.6967 3.19377 18.7148L3.19866 18.5234C3.24637 17.574 3.6442 16.6732 4.31877 15.9971L4.31975 15.9951L5.58244 14.7334V7.46777L3.57854 5.46387C3.058 4.94333 3.05801 4.09965 3.57854 3.5791ZM12.3989 22.417C12.4847 22.6324 12.6126 22.831 12.7797 22.998C13.1028 23.3209 13.5418 23.5022 13.9985 23.502C14.4553 23.5021 14.8949 23.3201 15.2182 22.9971C15.3851 22.8301 15.5142 22.632 15.6 22.417H12.3989ZM8.08244 15.251C8.08244 15.5825 7.9506 15.9013 7.71623 16.1357L6.08733 17.7637C5.83563 18.0165 5.69408 18.3589 5.69377 18.7158C5.69407 19.0345 5.82107 19.3402 6.04631 19.5654C6.27171 19.7906 6.57743 19.9169 6.89592 19.917H18.0317L8.08244 9.96777V15.251Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M13.9994 1.99707C18.6481 1.99713 22.4163 5.76612 22.4164 10.415V14.8398C22.4163 15.5301 21.8567 16.0898 21.1664 16.0898C20.4762 16.0898 19.9165 15.5301 19.9164 14.8398V10.415C19.9163 7.14648 17.2671 4.49713 13.9994 4.49707C12.8819 4.49707 11.8401 4.80572 10.9506 5.3418C10.3595 5.69813 9.59126 5.508 9.23479 4.91699C8.87845 4.32583 9.06855 3.55763 9.65959 3.20117C10.9277 2.4368 12.4143 1.99707 13.9994 1.99707Z"),
)
}.build()
return _ic_bell_cross_28!!
}
@Composable
@Preview(showBackground = true)
private fun IcBellCross28Preview() {
Icon(
imageVector = Icons.ic_bell_cross_28,
contentDescription = null,
)
}

View file

@ -31,7 +31,7 @@ val Icons.ic_binoculars_16: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M11.3098 3C12.4041 2.99991 13.3878 3.71042 13.673 4.7666L14.8517 9.12207C14.9489 9.4116 15.0021 9.71899 15.0021 10.0361C15.002 11.2515 14.2373 12.3277 13.0978 12.7793C11.9618 13.2292 10.6505 12.9823 9.77264 12.1396C9.25299 11.6407 8.95822 11.0064 8.88592 10.3535H7.11639C7.08557 10.6333 7.01479 10.9125 6.89862 11.1816C6.41743 12.296 5.29383 13.0036 4.06854 13.0039C2.84301 13.0039 1.7188 12.2962 1.23749 11.1816C0.96398 10.548 0.931868 9.86125 1.11639 9.23145L2.32538 4.7666C2.61062 3.71043 3.59427 2.99986 4.68866 3C5.82805 3.00037 6.8141 3.76776 7.06659 4.83105H8.93182C9.18435 3.76767 10.1702 3.00021 11.3098 3ZM5.36151 8.83496C4.64998 8.1551 3.48724 8.15532 2.77557 8.83496C2.2609 9.32689 2.11299 10.0565 2.38495 10.6865C2.65921 11.3213 3.31782 11.7539 4.06854 11.7539C4.81898 11.7536 5.47699 11.3211 5.75116 10.6865C5.84681 10.4649 5.88978 10.2306 5.88397 9.99902H5.88104V9.93262C5.85436 9.52928 5.6775 9.13717 5.36151 8.83496ZM12.6379 8.45508C11.9478 8.1817 11.157 8.33688 10.6389 8.83398C9.94391 9.50125 9.9439 10.57 10.6389 11.2373C11.157 11.7346 11.9477 11.8906 12.6379 11.6172C13.3244 11.345 13.752 10.7139 13.7521 10.0361C13.7521 9.89577 13.7326 9.7576 13.6974 9.62402L13.6926 9.62598L13.6535 9.48438C13.4905 9.03322 13.1319 8.65095 12.6379 8.45508ZM7.13104 9.10352H8.86737V6.08105H7.13104V9.10352ZM4.68768 4.25C4.12579 4.25014 3.66195 4.61281 3.53241 5.09277L2.93963 7.28223C3.90342 6.91459 5.01956 7.03899 5.88104 7.65137V5.36621C5.88089 4.77496 5.37151 4.25042 4.68768 4.25ZM11.3098 4.25C10.6257 4.25024 10.1175 4.77485 10.1174 5.36621V7.64746C10.9608 7.04783 12.0712 6.90363 13.0568 7.27832L12.466 5.09375C12.3365 4.61377 11.8716 4.25019 11.3098 4.25Z"),
pathData = addPathNodes("M11.3097 3C12.4041 2.99991 13.3878 3.71042 13.673 4.7666L14.8517 9.12207C14.9489 9.4116 15.0021 9.71899 15.0021 10.0361C15.002 11.2515 14.2373 12.3277 13.0978 12.7793C11.9618 13.2292 10.6505 12.9823 9.77263 12.1396C9.25299 11.6407 8.95821 11.0064 8.88592 10.3535H7.11638C7.08556 10.6333 7.01479 10.9125 6.89861 11.1816C6.41742 12.296 5.29382 13.0036 4.06853 13.0039C2.84301 13.0039 1.71879 12.2962 1.23748 11.1816C0.963972 10.548 0.93186 9.86125 1.11638 9.23145L2.32537 4.7666C2.61061 3.71043 3.59426 2.99986 4.68865 3C5.82804 3.00037 6.81409 3.76776 7.06658 4.83105H8.93181C9.18434 3.76767 10.1702 3.00021 11.3097 3ZM5.3615 8.83496C4.64997 8.1551 3.48724 8.15532 2.77556 8.83496C2.2609 9.32689 2.11298 10.0565 2.38494 10.6865C2.6592 11.3213 3.31781 11.7539 4.06853 11.7539C4.81898 11.7536 5.47698 11.3211 5.75115 10.6865C5.8468 10.4649 5.88977 10.2306 5.88396 9.99902H5.88103V9.93262C5.85435 9.52928 5.67749 9.13717 5.3615 8.83496ZM12.6379 8.45508C11.9478 8.1817 11.157 8.33688 10.6388 8.83398C9.9439 9.50125 9.9439 10.57 10.6388 11.2373C11.157 11.7346 11.9477 11.8906 12.6379 11.6172C13.3244 11.345 13.752 10.7139 13.7521 10.0361C13.7521 9.89577 13.7326 9.7576 13.6974 9.62402L13.6926 9.62598L13.6535 9.48438C13.4905 9.03322 13.1319 8.65095 12.6379 8.45508ZM7.13103 9.10352H8.86736V6.08105H7.13103V9.10352ZM4.68767 4.25C4.12578 4.25014 3.66194 4.61281 3.5324 5.09277L2.93963 7.28223C3.90341 6.91459 5.01955 7.03899 5.88103 7.65137V5.36621C5.88088 4.77496 5.3715 4.25042 4.68767 4.25ZM11.3097 4.25C10.6257 4.25024 10.1175 4.77485 10.1174 5.36621V7.64746C10.9608 7.04783 12.0712 6.90363 13.0568 7.27832L12.466 5.09375C12.3365 4.61377 11.8716 4.25019 11.3097 4.25Z"),
)
}.build()
return _ic_binoculars_16!!

View file

@ -31,7 +31,7 @@ val Icons.ic_binoculars_28: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M19.7578 5.00391C21.6512 5.08382 23.2755 6.39977 23.751 8.24805L25.7334 15.9453C25.9024 16.4714 25.9951 17.028 25.9951 17.5996C25.995 19.7768 24.6902 21.7452 22.6816 22.5811C20.6717 23.4172 18.3597 22.9512 16.8262 21.4053C15.9614 20.5334 15.4557 19.438 15.3076 18.3047H12.6846C12.6248 18.7649 12.509 19.2228 12.3272 19.665C11.499 21.679 9.54216 22.9979 7.36622 22.998C5.19023 22.998 3.23354 21.679 2.40528 19.665C1.95365 18.5664 1.8872 17.377 2.16797 16.2725L2.18067 16.2168C2.18644 16.1951 2.19123 16.173 2.19727 16.1514L4.23438 8.24902C4.72469 6.34088 6.43972 5.00092 8.41114 5.00098C10.4237 5.00098 12.1068 6.38144 12.5879 8.24219H15.3984C15.8795 6.38135 17.5618 5.00015 19.5742 5L19.7578 5.00391ZM9.38868 15.5566C8.27017 14.4341 6.46227 14.4341 5.34376 15.5566C4.52086 16.3827 4.27211 17.6296 4.71778 18.7139C5.1632 19.7968 6.21056 20.498 7.36622 20.498C8.52184 20.4979 9.5693 19.7969 10.0147 18.7139C10.1716 18.3321 10.2405 17.9298 10.2305 17.5332H10.2256V17.4111C10.1795 16.7245 9.89192 16.0619 9.38868 15.5566ZM21.7207 14.9268C20.6517 14.4821 19.4204 14.7281 18.6006 15.5547C17.4807 16.684 17.4808 18.5152 18.6006 19.6445C19.4204 20.4709 20.6518 20.7179 21.7207 20.2734C22.7909 19.8282 23.495 18.774 23.4951 17.5996C23.4951 17.3576 23.4631 17.121 23.4063 16.8936L23.3975 16.8965L23.334 16.6504C23.0688 15.8823 22.4904 15.2471 21.7207 14.9268ZM12.7256 10.7422V15.8047H15.2598V10.7422H12.7256ZM8.41114 7.5C7.59 7.49995 6.86494 8.05939 6.65626 8.87109L5.72852 12.4717C7.21662 11.9941 8.87032 12.1841 10.2256 13.043V9.33301C10.2254 8.31386 9.40615 7.5 8.41114 7.5ZM19.5742 7.5C18.5794 7.50017 17.7599 8.31397 17.7598 9.33301V13.041C19.0875 12.1979 20.7338 11.9753 22.2549 12.4619L21.3301 8.87207C21.1214 8.06026 20.3955 7.49981 19.5742 7.5Z"),
pathData = addPathNodes("M19.7578 5.00391C21.6512 5.08382 23.2755 6.39977 23.751 8.24805L25.7334 15.9453C25.9024 16.4714 25.9951 17.028 25.9951 17.5996C25.995 19.7768 24.6902 21.7452 22.6816 22.5811C20.6717 23.4172 18.3597 22.9512 16.8262 21.4053C15.9614 20.5334 15.4557 19.438 15.3076 18.3047H12.6846C12.6248 18.7649 12.509 19.2228 12.3272 19.665C11.499 21.679 9.54216 22.9979 7.36622 22.998C5.19023 22.998 3.23354 21.679 2.40528 19.665C1.95365 18.5664 1.8872 17.377 2.16797 16.2725L2.18067 16.2168C2.18644 16.1951 2.19123 16.173 2.19727 16.1514L4.23438 8.24902C4.72469 6.34088 6.43972 5.00092 8.41114 5.00098C10.4238 5.00098 12.1068 6.38144 12.5879 8.24219H15.3984C15.8795 6.38135 17.5618 5.00015 19.5742 5L19.7578 5.00391ZM9.38868 15.5566C8.27017 14.4341 6.46227 14.4341 5.34376 15.5566C4.52086 16.3827 4.27211 17.6296 4.71778 18.7139C5.1632 19.7968 6.21056 20.498 7.36622 20.498C8.52184 20.4979 9.5693 19.7969 10.0147 18.7139C10.1716 18.3321 10.2405 17.9298 10.2305 17.5332H10.2256V17.4111C10.1795 16.7245 9.89192 16.0619 9.38868 15.5566ZM21.7207 14.9268C20.6517 14.4821 19.4204 14.7281 18.6006 15.5547C17.4807 16.684 17.4808 18.5152 18.6006 19.6445C19.4204 20.4709 20.6518 20.7179 21.7207 20.2734C22.7909 19.8282 23.495 18.774 23.4951 17.5996C23.4951 17.3576 23.4631 17.121 23.4063 16.8936L23.3975 16.8965L23.334 16.6504C23.0688 15.8823 22.4904 15.2471 21.7207 14.9268ZM12.7256 10.7422V15.8047H15.2598V10.7422H12.7256ZM8.41114 7.5C7.59 7.49995 6.86494 8.05939 6.65626 8.87109L5.72852 12.4717C7.21662 11.9941 8.87032 12.1841 10.2256 13.043V9.33301C10.2254 8.31386 9.40615 7.5 8.41114 7.5ZM19.5742 7.5C18.5794 7.50017 17.7599 8.31397 17.7598 9.33301V13.041C19.0875 12.1979 20.7338 11.9753 22.2549 12.4619L21.3301 8.87207C21.1214 8.06026 20.3955 7.49981 19.5742 7.5Z"),
)
}.build()
return _ic_binoculars_28!!

View file

@ -31,7 +31,7 @@ val Icons.ic_binoculars_32: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M9.89423 6C12.0387 6.00016 13.8678 7.45751 14.362 9.45215H17.6306C18.1248 7.4579 19.9531 6.00129 22.0974 6.00098C24.176 6.00066 26.0186 7.37886 26.5495 9.39062L28.7116 17.5684C28.8987 18.1282 29.0006 18.7227 29.0007 19.335C29.0007 21.6402 27.5827 23.7003 25.4392 24.5693C23.2989 25.4366 20.8323 24.9573 19.1872 23.3418C18.2353 22.4068 17.6868 21.2255 17.5397 20.0059H14.4616C14.4005 20.5161 14.2692 21.0241 14.0622 21.5146C13.1663 23.6372 11.0628 25.0027 8.75068 25.0029C6.43857 25.0029 4.3362 23.637 3.44013 21.5146C2.92702 20.2989 2.87215 18.9796 3.22724 17.7705L5.44306 9.39062C5.97407 7.37893 7.81562 5.99967 9.89423 6ZM11.0563 17.1143C9.78538 15.8718 7.71717 15.8721 6.44599 17.1143C5.52052 18.0191 5.24876 19.3708 5.74286 20.542C6.23918 21.7174 7.42051 22.5029 8.75068 22.5029C10.0808 22.5027 11.2623 21.7175 11.7585 20.542C11.9323 20.1299 12.0095 19.6951 11.9987 19.2656H11.9948V19.1475C11.9472 18.398 11.626 17.6714 11.0563 17.1143ZM24.5007 16.418C23.275 15.9213 21.867 16.2016 20.9392 17.1123C19.6853 18.3439 19.6852 20.327 20.9392 21.5586C21.867 22.4697 23.2748 22.7487 24.5007 22.252C25.7223 21.7563 26.5007 20.5984 26.5007 19.335C26.5006 19.0741 26.4645 18.8182 26.4011 18.5713L26.3923 18.5742L26.3249 18.3193C26.0314 17.4804 25.383 16.7757 24.5007 16.418ZM14.4948 17.5059H17.4977V11.9521H14.4948V17.5059ZM9.89423 8.5C8.91961 8.49978 8.09346 9.14465 7.86005 10.0293L6.80536 14.0146C8.51381 13.4118 10.4539 13.6303 11.9948 14.6689V10.5332C11.9947 9.50323 11.189 8.61753 10.113 8.51074L9.89423 8.5ZM22.0983 8.5C20.9144 8.5 19.9979 9.43444 19.9977 10.5332V14.666C21.507 13.6479 23.4367 13.3915 25.1833 14.0059L24.1325 10.0303C23.9137 9.20092 23.1736 8.5817 22.279 8.50781L22.0983 8.5Z"),
pathData = addPathNodes("M9.89424 6C12.0387 6.00016 13.8678 7.45751 14.362 9.45215H17.6306C18.1248 7.4579 19.9531 6.00129 22.0974 6.00098C24.176 6.00066 26.0186 7.37886 26.5495 9.39062L28.7116 17.5684C28.8987 18.1282 29.0006 18.7227 29.0007 19.335C29.0007 21.6402 27.5827 23.7003 25.4392 24.5693C23.2989 25.4366 20.8323 24.9573 19.1872 23.3418C18.2353 22.4068 17.6868 21.2255 17.5397 20.0059H14.4616C14.4005 20.5161 14.2692 21.0241 14.0622 21.5146C13.1663 23.6372 11.0628 25.0027 8.75068 25.0029C6.43858 25.0029 4.33621 23.637 3.44014 21.5146C2.92702 20.2989 2.87216 18.9796 3.22725 17.7705L5.44307 9.39062C5.97408 7.37893 7.81563 5.99967 9.89424 6ZM11.0563 17.1143C9.78539 15.8718 7.71717 15.8721 6.446 17.1143C5.52053 18.0191 5.24877 19.3708 5.74287 20.542C6.23918 21.7174 7.42052 22.5029 8.75068 22.5029C10.0808 22.5027 11.2623 21.7175 11.7585 20.542C11.9323 20.1299 12.0095 19.6951 11.9987 19.2656H11.9948V19.1475C11.9472 18.398 11.626 17.6714 11.0563 17.1143ZM24.5007 16.418C23.275 15.9213 21.867 16.2016 20.9392 17.1123C19.6853 18.3439 19.6852 20.327 20.9392 21.5586C21.867 22.4697 23.2748 22.7487 24.5007 22.252C25.7223 21.7563 26.5007 20.5984 26.5007 19.335C26.5006 19.0741 26.4645 18.8182 26.4011 18.5713L26.3923 18.5742L26.3249 18.3193C26.0314 17.4804 25.383 16.7757 24.5007 16.418ZM14.4948 17.5059H17.4978V11.9521H14.4948V17.5059ZM9.89424 8.5C8.91962 8.49978 8.09347 9.14465 7.86006 10.0293L6.80537 14.0146C8.51382 13.4118 10.4539 13.6303 11.9948 14.6689V10.5332C11.9947 9.50323 11.189 8.61753 10.113 8.51074L9.89424 8.5ZM22.0983 8.5C20.9144 8.5 19.9979 9.43444 19.9978 10.5332V14.666C21.507 13.6479 23.4367 13.3915 25.1833 14.0059L24.1325 10.0303C23.9137 9.20092 23.1736 8.5817 22.279 8.50781L22.0983 8.5Z"),
)
}.build()
return _ic_binoculars_32!!

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_card_plus_28: ImageVector? = null
val Icons.ic_card_plus_28: ImageVector
get() {
if (_ic_card_plus_28 != null) return _ic_card_plus_28!!
_ic_card_plus_28 = ImageVector.Builder(
name = "ic_card_plus_28",
defaultWidth = 28.dp,
defaultHeight = 28.dp,
viewportWidth = 28f,
viewportHeight = 28f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M15.167 5.01758C15.8572 5.01775 16.417 5.57733 16.417 6.26758C16.4168 6.95766 15.8571 7.5174 15.167 7.51758H7C5.46193 7.51758 4.5 8.57993 4.5 9.55078V20C4.50021 21.3328 5.63626 22.5 7 22.5H21C22.3627 22.5 23.4998 21.3325 23.5 20V12.834C23.5 12.1436 24.0596 11.584 24.75 11.584C25.4404 11.584 26 12.1436 26 12.834V20C25.9998 22.6902 23.7663 25 21 25H7C4.31847 25 2.14036 22.8322 2.00684 20.251L2 20V9.55078C2 6.89524 4.40619 5.01758 7 5.01758H15.167ZM11.165 17.417C11.8552 17.4173 12.415 17.9768 12.415 18.667C12.4148 19.357 11.855 19.9167 11.165 19.917H8.16699C7.47676 19.917 6.91719 19.3572 6.91699 18.667C6.91699 17.9766 7.47664 17.417 8.16699 17.417H11.165ZM22.75 2.75C23.4404 2.75 24 3.30964 24 4V4.5H24.5C25.1904 4.5 25.75 5.05964 25.75 5.75C25.75 6.44036 25.1904 7 24.5 7H24V7.5C24 8.19036 23.4404 8.75 22.75 8.75C22.0596 8.75 21.5 8.19036 21.5 7.5V7H21C20.3096 7 19.75 6.44036 19.75 5.75C19.75 5.05964 20.3096 4.5 21 4.5H21.5V4C21.5 3.30964 22.0596 2.75 22.75 2.75Z"),
)
}.build()
return _ic_card_plus_28!!
}
@Composable
@Preview(showBackground = true)
private fun IcCardPlus28Preview() {
Icon(
imageVector = Icons.ic_card_plus_28,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chart_bar_vertical_16: ImageVector? = null
val Icons.ic_chart_bar_vertical_16: ImageVector
get() {
if (_ic_chart_bar_vertical_16 != null) return _ic_chart_bar_vertical_16!!
_ic_chart_bar_vertical_16 = ImageVector.Builder(
name = "ic_chart_bar_vertical_16",
defaultWidth = 16.dp,
defaultHeight = 16.dp,
viewportWidth = 16f,
viewportHeight = 16f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M11.75 3.125C12.5094 3.125 13.125 3.74061 13.125 4.5V11.5C13.125 12.2594 12.5094 12.875 11.75 12.875H4.25C3.49061 12.875 2.875 12.2594 2.875 11.5V10.25C2.875 9.49061 3.49061 8.875 4.25 8.875H5.875V7.25C5.875 6.49061 6.49061 5.875 7.25 5.875H8.875V4.5C8.875 3.74061 9.49061 3.125 10.25 3.125H11.75ZM4.25 10.125C4.18096 10.125 4.125 10.181 4.125 10.25V11.5C4.125 11.569 4.18096 11.625 4.25 11.625H5.875V10.125H4.25ZM7.25 7.125C7.18096 7.125 7.125 7.18096 7.125 7.25V11.625H8.875V7.125H7.25ZM10.25 4.375C10.181 4.375 10.125 4.43096 10.125 4.5V11.625H11.75C11.819 11.625 11.875 11.569 11.875 11.5V4.5C11.875 4.43096 11.819 4.375 11.75 4.375H10.25Z"),
)
}.build()
return _ic_chart_bar_vertical_16!!
}
@Composable
@Preview(showBackground = true)
private fun IcChartBarVertical16Preview() {
Icon(
imageVector = Icons.ic_chart_bar_vertical_16,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chart_bar_vertical_20: ImageVector? = null
val Icons.ic_chart_bar_vertical_20: ImageVector
get() {
if (_ic_chart_bar_vertical_20 != null) return _ic_chart_bar_vertical_20!!
_ic_chart_bar_vertical_20 = ImageVector.Builder(
name = "ic_chart_bar_vertical_20",
defaultWidth = 20.dp,
defaultHeight = 20.dp,
viewportWidth = 20f,
viewportHeight = 20f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M15.2949 3.25C16.2935 3.25041 17.1034 4.05997 17.1035 5.05859V14.9414C17.1034 15.9401 16.2935 16.7496 15.2949 16.75H7.90234C7.89585 16.7502 7.88934 16.751 7.88281 16.751H4.70605C3.70734 16.7509 2.89675 15.9401 2.89648 14.9414V13.1768C2.89661 12.178 3.70725 11.3683 4.70605 11.3682H7.13281V8.94141C7.13294 7.9426 7.9426 7.13294 8.94141 7.13281H11.3682V5.05859C11.3683 4.05979 12.178 3.25013 13.1768 3.25H15.2949ZM4.70605 12.8682C4.53568 12.8683 4.39759 13.0064 4.39746 13.1768V14.9414C4.39772 15.1117 4.53576 15.2509 4.70605 15.251H7.13281V12.8682H4.70605ZM8.94141 8.63281C8.77103 8.63294 8.63294 8.77103 8.63281 8.94141V15.25H11.3682V8.63281H8.94141ZM13.1768 4.75C13.0064 4.75013 12.8683 4.88822 12.8682 5.05859V15.25H15.2949C15.4651 15.2496 15.6034 15.1116 15.6035 14.9414V5.05859C15.6034 4.8884 15.4651 4.75041 15.2949 4.75H13.1768Z"),
)
}.build()
return _ic_chart_bar_vertical_20!!
}
@Composable
@Preview(showBackground = true)
private fun IcChartBarVertical20Preview() {
Icon(
imageVector = Icons.ic_chart_bar_vertical_20,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chart_bar_vertical_24: ImageVector? = null
val Icons.ic_chart_bar_vertical_24: ImageVector
get() {
if (_ic_chart_bar_vertical_24 != null) return _ic_chart_bar_vertical_24!!
_ic_chart_bar_vertical_24 = ImageVector.Builder(
name = "ic_chart_bar_vertical_24",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M19.0596 3C20.3913 3.00029 21.4717 4.08031 21.4717 5.41211V18.5879C21.4717 19.9197 20.3913 20.9997 19.0596 21H4.94141C3.60943 21 2.5293 19.9199 2.5293 18.5879V16.2354C2.52943 14.9035 3.60951 13.8232 4.94141 13.8232H8.17676V10.5889C8.17676 9.25689 9.25689 8.17676 10.5889 8.17676H13.8242V5.41211C13.8242 4.08013 14.9043 3 16.2363 3H19.0596ZM4.94141 15.8232C4.71408 15.8232 4.52943 16.0081 4.5293 16.2354V18.5879C4.5293 18.8153 4.71399 19 4.94141 19H8.17676V15.8232H4.94141ZM10.5889 10.1768C10.3615 10.1768 10.1768 10.3615 10.1768 10.5889V19H13.8242V10.1768H10.5889ZM16.2363 5C16.0089 5 15.8242 5.1847 15.8242 5.41211V19H19.0596C19.2867 18.9997 19.4717 18.8151 19.4717 18.5879V5.41211C19.4717 5.18488 19.2867 5.0003 19.0596 5H16.2363Z"),
)
}.build()
return _ic_chart_bar_vertical_24!!
}
@Composable
@Preview(showBackground = true)
private fun IcChartBarVertical24Preview() {
Icon(
imageVector = Icons.ic_chart_bar_vertical_24,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chart_bar_vertical_28: ImageVector? = null
val Icons.ic_chart_bar_vertical_28: ImageVector
get() {
if (_ic_chart_bar_vertical_28 != null) return _ic_chart_bar_vertical_28!!
_ic_chart_bar_vertical_28 = ImageVector.Builder(
name = "ic_chart_bar_vertical_28",
defaultWidth = 28.dp,
defaultHeight = 28.dp,
viewportWidth = 28f,
viewportHeight = 28f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M22.125 3.54004C23.7128 3.54004 25 4.82722 25 6.41504V21.582C24.9998 23.1697 23.7127 24.457 22.125 24.457H17.25C17.2438 24.457 17.2376 24.4561 17.2314 24.4561H5.875C4.28718 24.4561 3 23.1689 3 21.5811V18.873C3.00013 17.2853 4.28726 15.998 5.875 15.998H9.5V12.373C9.5002 10.7854 10.7873 9.49805 12.375 9.49805H16V6.41504C16 4.82722 17.2872 3.54004 18.875 3.54004H22.125ZM18.875 6.04004C18.6679 6.04004 18.5 6.20793 18.5 6.41504V21.957H22.125C22.332 21.957 22.4998 21.789 22.5 21.582V6.41504C22.5 6.20793 22.3321 6.04004 22.125 6.04004H18.875ZM5.875 18.498C5.66797 18.498 5.50013 18.6661 5.5 18.873V21.5811C5.5 21.7882 5.66789 21.9561 5.875 21.9561H9.5V18.498H5.875ZM12.375 11.998C12.168 11.998 12.0002 12.1661 12 12.373V21.9561H16V11.998H12.375Z"),
)
}.build()
return _ic_chart_bar_vertical_28!!
}
@Composable
@Preview(showBackground = true)
private fun IcChartBarVertical28Preview() {
Icon(
imageVector = Icons.ic_chart_bar_vertical_28,
contentDescription = null,
)
}

View file

@ -0,0 +1,62 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chart_line_vertical_16: ImageVector? = null
val Icons.ic_chart_line_vertical_16: ImageVector
get() {
if (_ic_chart_line_vertical_16 != null) return _ic_chart_line_vertical_16!!
_ic_chart_line_vertical_16 = ImageVector.Builder(
name = "ic_chart_line_vertical_16",
defaultWidth = 16.dp,
defaultHeight = 16.dp,
viewportWidth = 16f,
viewportHeight = 16f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M4.00098 9.59766C4.34573 9.59816 4.62598 9.87779 4.62598 10.2227V12C4.62578 12.3447 4.34561 12.6245 4.00098 12.625C3.65592 12.625 3.3752 12.345 3.375 12V10.2227C3.375 9.87748 3.6558 9.59766 4.00098 9.59766Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M6.66699 7.81934C7.01193 7.81957 7.29193 8.09936 7.29199 8.44434V12C7.29192 12.345 7.01193 12.6248 6.66699 12.625C6.32186 12.625 6.04206 12.3451 6.04199 12V8.44434C6.04206 8.09921 6.32185 7.81934 6.66699 7.81934Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M9.33398 5.59766C9.67896 5.59789 9.95898 5.87762 9.95898 6.22266V12C9.95879 12.3449 9.67884 12.6248 9.33398 12.625C8.98893 12.625 8.70918 12.345 8.70898 12V6.22266C8.70898 5.87748 8.98881 5.59766 9.33398 5.59766Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M12.001 3.375C12.3457 3.3755 12.626 3.65513 12.626 4V12C12.626 12.3449 12.3457 12.6245 12.001 12.625C11.6558 12.625 11.376 12.3452 11.376 12V4C11.376 3.65482 11.6558 3.375 12.001 3.375Z"),
)
}.build()
return _ic_chart_line_vertical_16!!
}
@Composable
@Preview(showBackground = true)
private fun IcChartLineVertical16Preview() {
Icon(
imageVector = Icons.ic_chart_line_vertical_16,
contentDescription = null,
)
}

View file

@ -0,0 +1,62 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chart_line_vertical_20: ImageVector? = null
val Icons.ic_chart_line_vertical_20: ImageVector
get() {
if (_ic_chart_line_vertical_20 != null) return _ic_chart_line_vertical_20!!
_ic_chart_line_vertical_20 = ImageVector.Builder(
name = "ic_chart_line_vertical_20",
defaultWidth = 20.dp,
defaultHeight = 20.dp,
viewportWidth = 20f,
viewportHeight = 20f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M4.31543 12.4082C4.72964 12.4082 5.06543 12.744 5.06543 13.1582V15.6846C5.06527 16.0986 4.72954 16.4346 4.31543 16.4346C3.90148 16.4344 3.56559 16.0985 3.56543 15.6846V13.1582C3.56543 12.7441 3.90138 12.4084 4.31543 12.4082Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M8.10547 9.88184C8.51946 9.8821 8.85547 10.2178 8.85547 10.6318V15.6846C8.85528 16.0985 8.51934 16.4343 8.10547 16.4346C7.69154 16.4344 7.35566 16.0985 7.35547 15.6846V10.6318C7.35547 10.2177 7.69142 9.88203 8.10547 9.88184Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M11.8945 6.72363C12.3087 6.72363 12.6445 7.05948 12.6445 7.47363V15.6846C12.6443 16.0986 12.3086 16.4346 11.8945 16.4346C11.4806 16.4344 11.1448 16.0985 11.1445 15.6846V7.47363C11.1446 7.0596 11.4805 6.72383 11.8945 6.72363Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M15.6846 3.56543C16.0984 3.56569 16.4344 3.90155 16.4346 4.31543V15.6836C16.4346 16.0976 16.0986 16.4333 15.6846 16.4336C15.2705 16.4334 14.9346 16.0977 14.9346 15.6836V4.31543C14.9348 3.9015 15.2706 3.56562 15.6846 3.56543Z"),
)
}.build()
return _ic_chart_line_vertical_20!!
}
@Composable
@Preview(showBackground = true)
private fun IcChartLineVertical20Preview() {
Icon(
imageVector = Icons.ic_chart_line_vertical_20,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chart_line_vertical_24: ImageVector? = null
val Icons.ic_chart_line_vertical_24: ImageVector
get() {
if (_ic_chart_line_vertical_24 != null) return _ic_chart_line_vertical_24!!
_ic_chart_line_vertical_24 = ImageVector.Builder(
name = "ic_chart_line_vertical_24",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M9.66699 11.7783C10.2191 11.7786 10.667 12.2262 10.667 12.7783V19.001C10.6665 19.5527 10.2187 20.0007 9.66699 20.001C9.11511 20.0009 8.66749 19.5528 8.66699 19.001V12.7783C8.66699 12.2261 9.11481 11.7784 9.66699 11.7783ZM5 14.8887C5.5522 14.8887 5.99987 15.3365 6 15.8887V19C5.99988 19.5522 5.55221 20 5 20C4.44789 19.9999 4.00012 19.5521 4 19V15.8887C4.00013 15.3366 4.4479 14.8888 5 14.8887ZM14.333 7.88867C14.8852 7.88867 15.3329 8.3365 15.333 8.88867V19C15.3329 19.5522 14.8852 20 14.333 20C13.7809 19.9999 13.3331 19.5521 13.333 19V8.88867C13.3331 8.33657 13.7809 7.88879 14.333 7.88867ZM19 4C19.5523 4 20 4.44772 20 5V19C20 19.5523 19.5523 20 19 20C18.4478 19.9999 18 19.5522 18 19V5C18 4.44779 18.4478 4.00012 19 4Z"),
)
}.build()
return _ic_chart_line_vertical_24!!
}
@Composable
@Preview(showBackground = true)
private fun IcChartLineVertical24Preview() {
Icon(
imageVector = Icons.ic_chart_line_vertical_24,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chart_line_vertical_28: ImageVector? = null
val Icons.ic_chart_line_vertical_28: ImageVector
get() {
if (_ic_chart_line_vertical_28 != null) return _ic_chart_line_vertical_28!!
_ic_chart_line_vertical_28 = ImageVector.Builder(
name = "ic_chart_line_vertical_28",
defaultWidth = 28.dp,
defaultHeight = 28.dp,
viewportWidth = 28f,
viewportHeight = 28f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M5.47363 17.4873C6.16399 17.4873 6.72363 18.0469 6.72363 18.7373V22.5264C6.72337 23.2165 6.16383 23.7764 5.47363 23.7764C4.78346 23.7763 4.2239 23.2165 4.22363 22.5264V18.7373C4.22363 18.047 4.7833 17.4873 5.47363 17.4873ZM11.1582 13.6973C11.8483 13.6975 12.4081 14.2571 12.4082 14.9473V22.5264C12.4081 23.2165 11.8483 23.7761 11.1582 23.7764C10.4679 23.7763 9.90829 23.2166 9.9082 22.5264V14.9473C9.90827 14.257 10.4679 13.6973 11.1582 13.6973ZM16.8428 8.96094C17.5329 8.9612 18.0928 9.52074 18.0928 10.2109V22.5264C18.0925 23.2163 17.5327 23.7761 16.8428 23.7764C16.1526 23.7763 15.593 23.2165 15.5928 22.5264V10.2109C15.5928 9.5206 16.1524 8.96097 16.8428 8.96094ZM22.5264 4.22363C23.2167 4.22363 23.7764 4.78328 23.7764 5.47363V22.5264C23.7763 23.2167 23.2167 23.7764 22.5264 23.7764C21.8361 23.7763 21.2764 23.2167 21.2764 22.5264V5.47363C21.2764 4.78329 21.836 4.22366 22.5264 4.22363Z"),
)
}.build()
return _ic_chart_line_vertical_28!!
}
@Composable
@Preview(showBackground = true)
private fun IcChartLineVertical28Preview() {
Icon(
imageVector = Icons.ic_chart_line_vertical_28,
contentDescription = null,
)
}

View file

@ -31,7 +31,7 @@ val Icons.ic_checkmark_24: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M18.2784 6.30768C18.6608 5.90939 19.294 5.89615 19.6924 6.27839C20.0907 6.66081 20.104 7.29407 19.7217 7.69245L10.1202 17.6924C9.93164 17.8888 9.67073 18 9.3985 18.0001C9.12638 18 8.86632 17.8887 8.6778 17.6924L4.27838 13.1124C3.89612 12.714 3.90943 12.0808 4.30768 11.6983C4.70604 11.3161 5.33929 11.3294 5.72174 11.7276L9.39752 15.5557L18.2784 6.30768Z"),
pathData = addPathNodes("M18.2784 6.30768C18.6608 5.90939 19.294 5.89615 19.6924 6.27839C20.0907 6.66081 20.104 7.29407 19.7217 7.69245L10.1202 17.6924C9.93164 17.8888 9.67073 18 9.3985 18.0001C9.12637 18 8.86632 17.8887 8.6778 17.6924L4.27838 13.1124C3.89612 12.714 3.90943 12.0808 4.30768 11.6983C4.70604 11.3161 5.33929 11.3294 5.72174 11.7276L9.39752 15.5557L18.2784 6.30768Z"),
)
}.build()
return _ic_checkmark_24!!

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_collapse_16: ImageVector? = null
val Icons.ic_chevron_collapse_16: ImageVector
get() {
if (_ic_chevron_collapse_16 != null) return _ic_chevron_collapse_16!!
_ic_chevron_collapse_16 = ImageVector.Builder(
name = "ic_chevron_collapse_16",
defaultWidth = 16.dp,
defaultHeight = 16.dp,
viewportWidth = 16f,
viewportHeight = 16f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M6.94727 8.42773C7.29176 8.42849 7.57108 8.70826 7.57129 9.05273L7.57227 13.2656C7.57207 13.6106 7.29135 13.8906 6.94629 13.8906C6.60123 13.8906 6.32051 13.6106 6.32031 13.2656L6.32129 9.67773L2.73242 9.66992C2.38735 9.66918 2.10876 9.38905 2.10938 9.04395C2.11008 8.699 2.38946 8.41956 2.73438 8.41992L6.94727 8.42773ZM9.05274 2.10938C9.39777 2.10954 9.67774 2.3893 9.67774 2.73438V6.32227L13.2646 6.32129C13.6098 6.32129 13.8896 6.60117 13.8896 6.94629C13.8896 7.29142 13.6098 7.57129 13.2646 7.57129H9.05274C8.70766 7.5712 8.42779 7.29137 8.42774 6.94629V2.73438C8.42774 2.38925 8.70763 2.10946 9.05274 2.10938Z"),
)
}.build()
return _ic_chevron_collapse_16!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronCollapse16Preview() {
Icon(
imageVector = Icons.ic_chevron_collapse_16,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_collapse_20: ImageVector? = null
val Icons.ic_chevron_collapse_20: ImageVector
get() {
if (_ic_chevron_collapse_20 != null) return _ic_chevron_collapse_20!!
_ic_chevron_collapse_20 = ImageVector.Builder(
name = "ic_chevron_collapse_20",
defaultWidth = 20.dp,
defaultHeight = 20.dp,
viewportWidth = 20f,
viewportHeight = 20f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M8.55762 10.6816C8.97099 10.6824 9.30616 11.0184 9.30664 11.4316V17.1846C9.30638 17.5986 8.97069 17.9336 8.55664 17.9336C8.14259 17.9336 7.80691 17.5986 7.80664 17.1846V12.1816L2.80371 12.1729C2.38955 12.1721 2.05396 11.8351 2.05469 11.4209C2.05548 11.007 2.39183 10.6715 2.80567 10.6719L8.55762 10.6816ZM11.4326 2.05469C11.8466 2.05485 12.1824 2.39076 12.1826 2.80469V7.80762L17.1846 7.80664C17.5985 7.80696 17.9345 8.14265 17.9346 8.55664C17.9345 8.97062 17.5985 9.30632 17.1846 9.30664H11.4316C11.0178 9.30622 10.6817 8.97055 10.6816 8.55664L10.6826 2.80469C10.6828 2.39069 11.0186 2.05474 11.4326 2.05469Z"),
)
}.build()
return _ic_chevron_collapse_20!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronCollapse20Preview() {
Icon(
imageVector = Icons.ic_chevron_collapse_20,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_collapse_24: ImageVector? = null
val Icons.ic_chevron_collapse_24: ImageVector
get() {
if (_ic_chevron_collapse_24 != null) return _ic_chevron_collapse_24!!
_ic_chevron_collapse_24 = ImageVector.Builder(
name = "ic_chevron_collapse_24",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M10.2559 12.751C10.8071 12.7523 11.2529 13.2006 11.2529 13.752V20.7471C11.2528 21.2991 10.8059 21.7468 10.2539 21.7471C9.7017 21.7471 9.25404 21.2992 9.25391 20.7471V14.75L3.25586 14.7383C2.70385 14.7371 2.257 14.2893 2.25781 13.7373C2.25879 13.1853 2.70686 12.7377 3.25879 12.7383L10.2559 12.751ZM13.751 2.25781C14.3033 2.25781 14.751 2.70553 14.751 3.25781L14.752 9.25391H20.7471C21.2992 9.25407 21.7471 9.70172 21.7471 10.2539C21.7467 10.8058 21.299 11.2528 20.7471 11.2529H13.752C13.1997 11.2529 12.7511 10.8051 12.751 10.2529V3.25781C12.751 2.70561 13.1988 2.25795 13.751 2.25781Z"),
)
}.build()
return _ic_chevron_collapse_24!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronCollapse24Preview() {
Icon(
imageVector = Icons.ic_chevron_collapse_24,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_collapse_28: ImageVector? = null
val Icons.ic_chevron_collapse_28: ImageVector
get() {
if (_ic_chevron_collapse_28 != null) return _ic_chevron_collapse_28!!
_ic_chevron_collapse_28 = ImageVector.Builder(
name = "ic_chevron_collapse_28",
defaultWidth = 28.dp,
defaultHeight = 28.dp,
viewportWidth = 28f,
viewportHeight = 28f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M11.9023 14.8711C12.5918 14.8723 13.1504 15.4326 13.1504 16.1221V24.5645C13.1503 25.2547 12.5907 25.8145 11.9004 25.8145C11.2101 25.8145 10.6505 25.2547 10.6504 24.5645V17.3701L3.45508 17.3564C2.76497 17.355 2.20589 16.7946 2.20703 16.1045C2.20826 15.4141 2.76962 14.8552 3.45996 14.8564L11.9023 14.8711ZM16.1221 2.20703C16.8121 2.20727 17.3719 2.76697 17.3721 3.45703V10.6504H24.5645C25.2544 10.6506 25.8141 11.2095 25.8145 11.8994C25.8145 12.5897 25.2546 13.1502 24.5645 13.1504H16.1221C15.4319 13.1503 14.8723 12.5905 14.8721 11.9004L14.8711 3.45703C14.8713 2.76686 15.4319 2.20708 16.1221 2.20703Z"),
)
}.build()
return _ic_chevron_collapse_28!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronCollapse28Preview() {
Icon(
imageVector = Icons.ic_chevron_collapse_28,
contentDescription = null,
)
}

View file

@ -0,0 +1,52 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_double_vertical_12: ImageVector? = null
val Icons.ic_chevron_double_vertical_12: ImageVector
get() {
if (_ic_chevron_double_vertical_12 != null) return _ic_chevron_double_vertical_12!!
_ic_chevron_double_vertical_12 = ImageVector.Builder(
name = "ic_chevron_double_vertical_12",
defaultWidth = 12.dp,
defaultHeight = 12.dp,
viewportWidth = 12f,
viewportHeight = 12f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M8.1537 7.2485C8.35319 7.05806 8.66997 7.06512 8.86073 7.26413C9.05129 7.46373 9.04446 7.78044 8.8451 7.97116L6.3451 10.3579C6.15188 10.5423 5.84689 10.5423 5.6537 10.3579L3.1537 7.97116C2.95472 7.78043 2.9477 7.46362 3.13807 7.26413C3.32868 7.06489 3.64548 7.05829 3.8451 7.2485L5.9994 9.30612L8.1537 7.2485Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M5.6537 1.63815C5.84678 1.45382 6.15186 1.45408 6.3451 1.63815L8.8451 4.02487C9.04446 4.2156 9.05129 4.5323 8.86073 4.7319C8.67 4.93123 8.35329 4.93808 8.1537 4.74753L5.9994 2.68991L3.8451 4.74753C3.6455 4.93804 3.32878 4.93124 3.13807 4.7319C2.94793 4.53229 2.95453 4.21547 3.1537 4.02487L5.6537 1.63815Z"),
)
}.build()
return _ic_chevron_double_vertical_12!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronDoubleVertical12Preview() {
Icon(
imageVector = Icons.ic_chevron_double_vertical_12,
contentDescription = null,
)
}

View file

@ -0,0 +1,52 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_double_vertical_16: ImageVector? = null
val Icons.ic_chevron_double_vertical_16: ImageVector
get() {
if (_ic_chevron_double_vertical_16 != null) return _ic_chevron_double_vertical_16!!
_ic_chevron_double_vertical_16 = ImageVector.Builder(
name = "ic_chevron_double_vertical_16",
defaultWidth = 16.dp,
defaultHeight = 16.dp,
viewportWidth = 16f,
viewportHeight = 16f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M10.9306 9.53027C11.1738 9.28531 11.5694 9.28322 11.8144 9.52637C12.0592 9.76954 12.0604 10.1652 11.8173 10.4102L8.44232 13.8105C8.32502 13.9286 8.1654 13.9951 7.99896 13.9951C7.83254 13.9951 7.67292 13.9286 7.5556 13.8105L4.1806 10.4102C3.93746 10.1652 3.93857 9.76953 4.18353 9.52637C4.42851 9.28322 4.82416 9.28531 5.06732 9.53027L7.99896 12.4834L10.9306 9.53027Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M7.99896 2C8.16534 2.00003 8.32504 2.06658 8.44232 2.18457L11.8173 5.58496C12.0604 5.82986 12.0591 6.22556 11.8144 6.46875C11.5694 6.7119 11.1738 6.70981 10.9306 6.46484L7.99896 3.51172L5.06732 6.46484C4.82416 6.70981 4.42851 6.7119 4.18353 6.46875C3.9387 6.22557 3.9375 5.82989 4.1806 5.58496L7.5556 2.18457C7.6729 2.06662 7.8326 2 7.99896 2Z"),
)
}.build()
return _ic_chevron_double_vertical_16!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronDoubleVertical16Preview() {
Icon(
imageVector = Icons.ic_chevron_double_vertical_16,
contentDescription = null,
)
}

View file

@ -0,0 +1,52 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_double_vertical_20: ImageVector? = null
val Icons.ic_chevron_double_vertical_20: ImageVector
get() {
if (_ic_chevron_double_vertical_20 != null) return _ic_chevron_double_vertical_20!!
_ic_chevron_double_vertical_20 = ImageVector.Builder(
name = "ic_chevron_double_vertical_20",
defaultWidth = 20.dp,
defaultHeight = 20.dp,
viewportWidth = 20f,
viewportHeight = 20f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M13.2221 11.9663C13.5149 11.6737 13.9898 11.6737 14.2827 11.9663C14.5755 12.2591 14.5755 12.7349 14.2827 13.0278L10.5307 16.7797C10.2378 17.0726 9.76208 17.0726 9.46918 16.7797L5.71723 13.0278C5.42434 12.7349 5.42434 12.2591 5.71723 11.9663C6.01006 11.6737 6.48496 11.6737 6.77777 11.9663L10.0004 15.1889L13.2221 11.9663Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M9.46918 3.22016C9.76207 2.92726 10.2378 2.92726 10.5307 3.22016L14.2827 6.97211C14.5752 7.26503 14.5754 7.74086 14.2827 8.03363C13.9899 8.32606 13.515 8.32585 13.2221 8.03363L10.0004 4.81098L6.77777 8.03363C6.48506 8.32605 6.01008 8.32585 5.71723 8.03363C5.42435 7.74075 5.42437 7.26501 5.71723 6.97211L9.46918 3.22016Z"),
)
}.build()
return _ic_chevron_double_vertical_20!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronDoubleVertical20Preview() {
Icon(
imageVector = Icons.ic_chevron_double_vertical_20,
contentDescription = null,
)
}

View file

@ -0,0 +1,52 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_double_vertical_24: ImageVector? = null
val Icons.ic_chevron_double_vertical_24: ImageVector
get() {
if (_ic_chevron_double_vertical_24 != null) return _ic_chevron_double_vertical_24!!
_ic_chevron_double_vertical_24 = ImageVector.Builder(
name = "ic_chevron_double_vertical_24",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M16.2929 14.293C16.6834 13.9025 17.3164 13.9025 17.707 14.293C18.0974 14.6835 18.0974 15.3165 17.707 15.707L12.707 20.707C12.5194 20.8945 12.2651 21 11.9999 21C11.7347 21 11.4804 20.8945 11.2929 20.707L6.29289 15.707C5.90237 15.3165 5.90237 14.6835 6.29289 14.293C6.68342 13.9025 7.31644 13.9025 7.70696 14.293L11.9999 18.5859L16.2929 14.293Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M11.9999 2.99902C12.265 2.99904 12.5195 3.1046 12.707 3.29199L17.707 8.29297C18.0972 8.68352 18.0974 9.3166 17.707 9.70703C17.3164 10.0973 16.6833 10.0965 16.2929 9.70605L11.9999 5.41309L7.70696 9.70605C7.31643 10.0966 6.68342 10.0966 6.29289 9.70605C5.90258 9.31551 5.90244 8.68245 6.29289 8.29199L11.2929 3.29199C11.4804 3.10463 11.7348 2.99902 11.9999 2.99902Z"),
)
}.build()
return _ic_chevron_double_vertical_24!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronDoubleVertical24Preview() {
Icon(
imageVector = Icons.ic_chevron_double_vertical_24,
contentDescription = null,
)
}

View file

@ -0,0 +1,52 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_double_vertical_28: ImageVector? = null
val Icons.ic_chevron_double_vertical_28: ImageVector
get() {
if (_ic_chevron_double_vertical_28 != null) return _ic_chevron_double_vertical_28!!
_ic_chevron_double_vertical_28 = ImageVector.Builder(
name = "ic_chevron_double_vertical_28",
defaultWidth = 28.dp,
defaultHeight = 28.dp,
viewportWidth = 28f,
viewportHeight = 28f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M19.3851 16.8481C19.8831 16.3702 20.6737 16.3863 21.1517 16.8842C21.6296 17.3822 21.6133 18.1728 21.1156 18.6508L14.8656 24.6508C14.3819 25.1151 13.6188 25.115 13.1351 24.6508L6.88508 18.6508C6.38708 18.1727 6.3709 17.3822 6.84895 16.8842C7.32705 16.3864 8.1176 16.3701 8.61555 16.8481L14.0003 22.018L19.3851 16.8481Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M13.1351 3.3481C13.6188 2.88406 14.382 2.88388 14.8656 3.3481L21.1156 9.3481C21.6134 9.82609 21.6295 10.6167 21.1517 11.1147C20.6736 11.6127 19.8831 11.6288 19.3851 11.1508L14.0003 5.98091L8.61555 11.1508C8.11755 11.6289 7.32703 11.6127 6.84895 11.1147C6.3709 10.6167 6.38708 9.82618 6.88508 9.3481L13.1351 3.3481Z"),
)
}.build()
return _ic_chevron_double_vertical_28!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronDoubleVertical28Preview() {
Icon(
imageVector = Icons.ic_chevron_double_vertical_28,
contentDescription = null,
)
}

View file

@ -0,0 +1,52 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_double_vertical_32: ImageVector? = null
val Icons.ic_chevron_double_vertical_32: ImageVector
get() {
if (_ic_chevron_double_vertical_32 != null) return _ic_chevron_double_vertical_32!!
_ic_chevron_double_vertical_32 = ImageVector.Builder(
name = "ic_chevron_double_vertical_32",
defaultWidth = 32.dp,
defaultHeight = 32.dp,
viewportWidth = 32f,
viewportHeight = 32f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M21.5099 19.1094C22.0567 18.563 22.9438 18.5628 23.4904 19.1094C24.037 19.656 24.0367 20.5431 23.4904 21.0898L16.9904 27.5898C16.7279 27.8523 16.3713 27.9999 16.0001 28C15.6288 28 15.2725 27.8524 15.0099 27.5898L8.5099 21.0898C7.96317 20.5431 7.96317 19.6561 8.5099 19.1094C9.05667 18.563 9.94377 18.5628 10.4904 19.1094L16.0001 24.6191L21.5099 19.1094Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M16.0001 4C16.3713 4.0001 16.7279 4.1477 16.9904 4.41016L23.4904 10.9102C24.0369 11.4568 24.0368 12.3439 23.4904 12.8906C22.9437 13.4373 22.0566 13.4373 21.5099 12.8906L16.0001 7.38086L10.4904 12.8906C9.94366 13.4373 9.05664 13.4373 8.5099 12.8906C7.96317 12.3439 7.96317 11.4569 8.5099 10.9102L15.0099 4.41016C15.2724 4.1478 15.629 4 16.0001 4Z"),
)
}.build()
return _ic_chevron_double_vertical_32!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronDoubleVertical32Preview() {
Icon(
imageVector = Icons.ic_chevron_double_vertical_32,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_expand_16: ImageVector? = null
val Icons.ic_chevron_expand_16: ImageVector
get() {
if (_ic_chevron_expand_16 != null) return _ic_chevron_expand_16!!
_ic_chevron_expand_16 = ImageVector.Builder(
name = "ic_chevron_expand_16",
defaultWidth = 16.dp,
defaultHeight = 16.dp,
viewportWidth = 16f,
viewportHeight = 16f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M3.65039 7.375C3.99521 7.37526 4.27518 7.65516 4.27539 8V11.7256H8C8.34495 11.7258 8.625 12.0056 8.625 12.3506C8.6247 12.6953 8.34477 12.9753 8 12.9756H4.15039C3.52926 12.9756 3.02472 12.4716 3.02441 11.8506V8C3.02463 7.655 3.30534 7.375 3.65039 7.375ZM11.8506 3.02539C12.4716 3.02576 12.9756 3.5293 12.9756 4.15039V8C12.9754 8.34478 12.6953 8.62463 12.3506 8.625C12.0055 8.625 11.7258 8.34501 11.7256 8V4.27539H8C7.65512 4.27518 7.3752 3.99527 7.375 3.65039C7.375 3.30534 7.655 3.0256 8 3.02539H11.8506Z"),
)
}.build()
return _ic_chevron_expand_16!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronExpand16Preview() {
Icon(
imageVector = Icons.ic_chevron_expand_16,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_expand_20: ImageVector? = null
val Icons.ic_chevron_expand_20: ImageVector
get() {
if (_ic_chevron_expand_20 != null) return _ic_chevron_expand_20!!
_ic_chevron_expand_20 = ImageVector.Builder(
name = "ic_chevron_expand_20",
defaultWidth = 20.dp,
defaultHeight = 20.dp,
viewportWidth = 20f,
viewportHeight = 20f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M3.75 9.25C4.16421 9.25 4.5 9.58579 4.5 10V15.5H10C10.4142 15.5 10.75 15.8358 10.75 16.25C10.75 16.6642 10.4142 17 10 17H4.5C3.67157 17 3 16.3284 3 15.5V10C3 9.58579 3.33579 9.25 3.75 9.25ZM15.5 3C16.3284 3 17 3.67157 17 4.5V10C17 10.4142 16.6642 10.75 16.25 10.75C15.8358 10.75 15.5 10.4142 15.5 10V4.5H10C9.58579 4.5 9.25 4.16421 9.25 3.75C9.25 3.33579 9.58579 3 10 3H15.5Z"),
)
}.build()
return _ic_chevron_expand_20!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronExpand20Preview() {
Icon(
imageVector = Icons.ic_chevron_expand_20,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_expand_24: ImageVector? = null
val Icons.ic_chevron_expand_24: ImageVector
get() {
if (_ic_chevron_expand_24 != null) return _ic_chevron_expand_24!!
_ic_chevron_expand_24 = ImageVector.Builder(
name = "ic_chevron_expand_24",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M4 11C4.55228 11 5 11.4477 5 12V19H12C12.5523 19 13 19.4477 13 20C13 20.5523 12.5523 21 12 21H5C3.89543 21 3 20.1046 3 19V12C3 11.4477 3.44772 11 4 11ZM19 3C20.1046 3 21 3.89543 21 5V12C21 12.5523 20.5523 13 20 13C19.4477 13 19 12.5523 19 12V5H12C11.4477 5 11 4.55228 11 4C11 3.44772 11.4477 3 12 3H19Z"),
)
}.build()
return _ic_chevron_expand_24!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronExpand24Preview() {
Icon(
imageVector = Icons.ic_chevron_expand_24,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_chevron_expand_28: ImageVector? = null
val Icons.ic_chevron_expand_28: ImageVector
get() {
if (_ic_chevron_expand_28 != null) return _ic_chevron_expand_28!!
_ic_chevron_expand_28 = ImageVector.Builder(
name = "ic_chevron_expand_28",
defaultWidth = 28.dp,
defaultHeight = 28.dp,
viewportWidth = 28f,
viewportHeight = 28f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M4 12.75C4.69036 12.75 5.25 13.3096 5.25 14V22.5C5.25 22.6381 5.36193 22.75 5.5 22.75H14C14.6904 22.75 15.25 23.3096 15.25 24C15.25 24.6904 14.6904 25.25 14 25.25H5.5C3.98122 25.25 2.75 24.0188 2.75 22.5V14C2.75 13.3096 3.30964 12.75 4 12.75ZM22.5 2.75C24.0188 2.75 25.25 3.98122 25.25 5.5V14C25.25 14.6904 24.6904 15.25 24 15.25C23.3096 15.25 22.75 14.6904 22.75 14V5.5C22.75 5.36193 22.6381 5.25 22.5 5.25H14C13.3096 5.25 12.75 4.69036 12.75 4C12.75 3.30964 13.3096 2.75 14 2.75H22.5Z"),
)
}.build()
return _ic_chevron_expand_28!!
}
@Composable
@Preview(showBackground = true)
private fun IcChevronExpand28Preview() {
Icon(
imageVector = Icons.ic_chevron_expand_28,
contentDescription = null,
)
}

View file

@ -31,7 +31,7 @@ val Icons.ic_chevron_left_12: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M6.89468 2.14332C7.08983 1.94822 7.40643 1.94842 7.60171 2.14332C7.79632 2.33861 7.79671 2.65529 7.60171 2.85035L4.45425 5.99781L7.60171 9.14527C7.79645 9.34056 7.79676 9.65721 7.60171 9.8523C7.4066 10.0472 7.08993 10.047 6.89468 9.8523L3.3937 6.35133C3.19885 6.1561 3.19873 5.83945 3.3937 5.64429L6.89468 2.14332Z"),
pathData = addPathNodes("M6.89468 2.14332C7.08983 1.94822 7.40643 1.94842 7.60171 2.14332C7.79632 2.33861 7.79671 2.65529 7.60171 2.85035L4.45425 5.99781L7.60171 9.14527C7.79645 9.34056 7.79676 9.65721 7.60171 9.8523C7.4066 10.0472 7.08993 10.047 6.89468 9.8523L3.3937 6.35133C3.19885 6.15609 3.19873 5.83945 3.3937 5.64429L6.89468 2.14332Z"),
)
}.build()
return _ic_chevron_left_12!!

View file

@ -31,7 +31,7 @@ val Icons.ic_chevron_left_16: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M9.1167 3.18182C9.36075 2.93815 9.75749 2.93803 10.0015 3.18182C10.2452 3.42566 10.2448 3.82152 10.0015 4.06561L6.0708 7.99725L10.0015 11.9269C10.2454 12.1709 10.2452 12.5676 10.0015 12.8117C9.7574 13.0557 9.36077 13.0557 9.1167 12.8117L4.74463 8.43866C4.50075 8.19459 4.50068 7.79889 4.74463 7.55487L9.1167 3.18182Z"),
pathData = addPathNodes("M9.1167 3.18182C9.36075 2.93815 9.75749 2.93803 10.0015 3.18182C10.2452 3.42566 10.2448 3.82152 10.0015 4.06561L6.0708 7.99725L10.0015 11.9269C10.2454 12.1709 10.2452 12.5676 10.0015 12.8117C9.7574 13.0557 9.36077 13.0557 9.1167 12.8117L4.74463 8.43866C4.50075 8.19459 4.50068 7.7989 4.74463 7.55487L9.1167 3.18182Z"),
)
}.build()
return _ic_chevron_left_16!!

View file

@ -31,7 +31,7 @@ val Icons.ic_chevron_left_20: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M11.7031 3.21976C11.9959 2.92697 12.4708 2.92718 12.7637 3.21976C13.0561 3.51268 13.0564 3.98756 12.7637 4.2803L7.04395 10.002L12.7637 15.7227C13.0561 16.0156 13.0564 16.4905 12.7637 16.7832C12.4709 17.0759 11.996 17.0757 11.7031 16.7832L5.45118 10.5323C5.15861 10.2393 5.15843 9.76353 5.45118 9.47073L11.7031 3.21976Z"),
pathData = addPathNodes("M11.7031 3.21976C11.9959 2.92697 12.4708 2.92718 12.7637 3.21976C13.0561 3.51268 13.0564 3.98756 12.7637 4.2803L7.04395 10.002L12.7637 15.7227C13.0561 16.0156 13.0564 16.4905 12.7637 16.7832C12.4709 17.0759 11.996 17.0757 11.7031 16.7832L5.45118 10.5323C5.15861 10.2393 5.15843 9.76352 5.45118 9.47073L11.7031 3.21976Z"),
)
}.build()
return _ic_chevron_left_20!!

View file

@ -31,7 +31,7 @@ val Icons.ic_chevron_right_28: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M9.99008 4.36269C10.4783 3.87543 11.2698 3.87497 11.7577 4.36269L20.5096 13.1146C20.7434 13.3488 20.8746 13.6675 20.8748 13.9984C20.8747 14.3294 20.7434 14.648 20.5096 14.8822L11.7577 23.6332C11.2696 24.1213 10.4782 24.1212 9.99008 23.6332C9.502 23.145 9.50195 22.3538 9.99008 21.8656L17.8573 13.9984L9.99008 6.13027C9.50207 5.6421 9.50197 4.8508 9.99008 4.36269Z"),
pathData = addPathNodes("M9.99008 4.36269C10.4783 3.87543 11.2698 3.87497 11.7577 4.36269L20.5096 13.1146C20.7434 13.3488 20.8746 13.6675 20.8748 13.9984C20.8747 14.3294 20.7434 14.648 20.5096 14.8822L11.7577 23.6332C11.2696 24.1213 10.4782 24.1212 9.99008 23.6332C9.502 23.145 9.50195 22.3537 9.99008 21.8656L17.8573 13.9984L9.99008 6.13027C9.50207 5.6421 9.50197 4.8508 9.99008 4.36269Z"),
)
}.build()
return _ic_chevron_right_28!!

View file

@ -31,7 +31,7 @@ val Icons.ic_clock_16: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M8.36523 4.5C8.71001 4.50033 8.99003 4.7802 8.99023 5.125V8.26074C8.99023 8.60572 8.71014 8.88542 8.36523 8.88574H6.125C5.77982 8.88574 5.5 8.60592 5.5 8.26074C5.50026 7.91578 5.77998 7.63574 6.125 7.63574H7.74023V5.125C7.74044 4.77999 8.02018 4.5 8.36523 4.5Z"),
pathData = addPathNodes("M8.36523 4.5C8.71001 4.50033 8.99003 4.7802 8.99023 5.125V8.26074C8.99023 8.60572 8.71014 8.88542 8.36523 8.88574H6.125C5.77982 8.88574 5.5 8.60592 5.5 8.26074C5.50026 7.91578 5.77998 7.63574 6.125 7.63574H7.74023V5.125C7.74044 4.78 8.02018 4.5 8.36523 4.5Z"),
)
addPath(
fill = SolidColor(Color.Black),

View file

@ -31,7 +31,7 @@ val Icons.ic_cloud_16: ImageVector
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M8 3.375C10.1072 3.375 11.8925 4.86911 12.1826 6.8584C13.556 7.11784 14.6248 8.27613 14.625 9.71387C14.625 11.3498 13.2412 12.625 11.5996 12.625H5C3.02705 12.625 1.375 11.0941 1.375 9.14258L1.37891 8.97754C1.45745 7.41255 2.61167 6.12397 4.14746 5.77051C4.82684 4.31304 6.33845 3.37577 8 3.375ZM8 4.625C6.70774 4.62572 5.58437 5.40923 5.18262 6.53516C5.10338 6.75663 4.90621 6.9146 4.67285 6.94434C3.47814 7.09672 2.62729 8.05592 2.625 9.14355C2.6254 10.3476 3.6595 11.375 5 11.375H11.5996C12.609 11.375 13.375 10.6027 13.375 9.71387C13.3748 8.82524 12.6088 8.05371 11.5996 8.05371C11.2547 8.0535 10.9747 7.77369 10.9746 7.42871C10.9746 5.90873 9.67213 4.625 8 4.625Z"),
pathData = addPathNodes("M8 3.375C10.1072 3.375 11.8925 4.86911 12.1826 6.8584C13.556 7.11784 14.6248 8.27613 14.625 9.71387C14.625 11.3498 13.2412 12.625 11.5996 12.625H5C3.02705 12.625 1.375 11.0941 1.375 9.14258L1.37891 8.97754C1.45745 7.41255 2.61167 6.12397 4.14746 5.77051C4.82684 4.31304 6.33845 3.37577 8 3.375ZM8 4.625C6.70774 4.62572 5.58437 5.40923 5.18262 6.53516C5.10338 6.75663 4.90622 6.9146 4.67285 6.94434C3.47814 7.09672 2.62729 8.05592 2.625 9.14355C2.6254 10.3476 3.6595 11.375 5 11.375H11.5996C12.609 11.375 13.375 10.6027 13.375 9.71387C13.3748 8.82524 12.6088 8.05371 11.5996 8.05371C11.2547 8.0535 10.9747 7.77369 10.9746 7.42871C10.9746 5.90873 9.67213 4.625 8 4.625Z"),
)
}.build()
return _ic_cloud_16!!

View file

@ -0,0 +1,57 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_cloud_exclamation_12: ImageVector? = null
val Icons.ic_cloud_exclamation_12: ImageVector
get() {
if (_ic_cloud_exclamation_12 != null) return _ic_cloud_exclamation_12!!
_ic_cloud_exclamation_12 = ImageVector.Builder(
name = "ic_cloud_exclamation_12",
defaultWidth = 12.dp,
defaultHeight = 12.dp,
viewportWidth = 12f,
viewportHeight = 12f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M6.26517 3.05908C7.42958 3.17736 8.36402 4.06566 8.5591 5.20752C9.38613 5.41333 10 6.16014 10 7.05225C9.99971 8.10281 9.14877 8.95459 8.09993 8.95459H7.39995C7.12447 8.95451 6.901 8.73051 6.9008 8.45459C6.90089 8.17857 7.1244 7.95467 7.39995 7.95459H8.09993C8.59743 7.95459 9.00142 7.55053 9.00171 7.05225C9.00171 6.55372 8.5976 6.14893 8.09993 6.14893C7.82452 6.14876 7.60098 5.9248 7.60078 5.64893C7.60054 4.81872 6.97097 4.13545 6.16378 4.05322L6 4.04541C5.31481 4.04578 4.70548 4.48343 4.48501 5.1333C4.4238 5.31271 4.26613 5.44214 4.07848 5.46729C3.46085 5.55029 2.99941 6.07836 2.99829 6.70264C2.99915 7.39397 3.55879 7.95437 4.24909 7.95459H4.59907C4.87469 7.95459 5.09814 8.17852 5.09822 8.45459C5.09802 8.73056 4.87462 8.95459 4.59907 8.95459H4.24909C3.00712 8.95437 2.00033 7.94572 2 6.70166L2.00975 6.4917C2.09751 5.55953 2.75664 4.78231 3.65245 4.5376C4.07741 3.63546 4.98679 3.0459 6 3.04541L6.26517 3.05908Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M6.01462 7.85107C6.04128 7.85178 6.06777 7.85445 6.09359 7.85889C6.1 7.8601 6.10677 7.86133 6.11309 7.86279C6.28798 7.89958 6.43781 8.01846 6.5089 8.18799C6.59509 8.39401 6.5488 8.63184 6.39191 8.79053C6.23455 8.94915 5.99683 8.99761 5.7904 8.9126C5.58397 8.82733 5.44936 8.6255 5.44918 8.40186V8.39893C5.45041 8.11144 5.67078 7.87878 5.95126 7.854C5.96625 7.85249 5.98171 7.84922 5.99708 7.84912L5.99903 7.8501L6.00195 7.84912L6.01462 7.85107Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M6.00098 5.49951C6.27618 5.50002 6.50006 5.72374 6.50012 5.99951V7.05127C6.50012 7.3271 6.27622 7.55076 6.00098 7.55127C5.7253 7.55127 5.50183 7.32741 5.50183 7.05127V5.99951C5.50189 5.72343 5.72534 5.49951 6.00098 5.49951Z"),
)
}.build()
return _ic_cloud_exclamation_12!!
}
@Composable
@Preview(showBackground = true)
private fun IcCloudExclamation12Preview() {
Icon(
imageVector = Icons.ic_cloud_exclamation_12,
contentDescription = null,
)
}

View file

@ -0,0 +1,57 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_cloud_exclamation_16: ImageVector? = null
val Icons.ic_cloud_exclamation_16: ImageVector
get() {
if (_ic_cloud_exclamation_16 != null) return _ic_cloud_exclamation_16!!
_ic_cloud_exclamation_16 = ImageVector.Builder(
name = "ic_cloud_exclamation_16",
defaultWidth = 16.dp,
defaultHeight = 16.dp,
viewportWidth = 16f,
viewportHeight = 16f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M8.00098 3.61426C9.935 3.6147 11.5354 5.04182 11.8076 6.90039C13.0592 7.16864 13.998 8.28063 13.998 9.6123C13.9978 11.1438 12.7561 12.3852 11.2246 12.3857H10.1494C9.80437 12.3856 9.52447 12.1058 9.52441 11.7607C9.52453 11.4157 9.80441 11.1359 10.1494 11.1357H11.2246C12.0657 11.1352 12.7478 10.4535 12.748 9.6123C12.748 8.7709 12.0659 8.0884 11.2246 8.08789C10.8795 8.08789 10.5997 7.808 10.5996 7.46289C10.5996 6.11772 9.57654 5.0114 8.2666 4.87793L8.00098 4.86426C6.88901 4.8648 5.90082 5.57318 5.54297 6.62598C5.46667 6.8505 5.26912 7.01218 5.03418 7.04395C4.01595 7.18016 3.25477 8.04888 3.25293 9.07617C3.25382 10.2139 4.17657 11.1357 5.31445 11.1357H5.85156C6.19642 11.136 6.47645 11.4158 6.47656 11.7607C6.4765 12.1057 6.19646 12.3855 5.85156 12.3857H5.31445C3.4857 12.3857 2.00201 10.903 2.00195 9.07422L2.01758 8.7666C2.14882 7.37552 3.14695 6.21901 4.49707 5.87891C5.11374 4.51207 6.47882 3.6151 8.00098 3.61426Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M7.95898 7.5166C8.304 7.51672 8.58387 7.79659 8.58398 8.1416V9.80469C8.58382 10.1497 8.30396 10.4296 7.95898 10.4297C7.61402 10.4296 7.33415 10.1496 7.33398 9.80469V8.1416C7.3341 7.7966 7.61399 7.51673 7.95898 7.5166Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M7.96973 10.9775C8.21463 10.9812 8.43805 11.1089 8.56348 11.3145L8.6123 11.4092L8.64551 11.5107C8.70539 11.7489 8.63766 12.0048 8.46094 12.1826C8.25881 12.3856 7.95437 12.447 7.68945 12.3379C7.42444 12.2286 7.25117 11.9702 7.25098 11.6836V11.6807C7.25216 11.3064 7.5441 11.0044 7.91211 10.9805C7.92598 10.9794 7.93999 10.9757 7.9541 10.9756L7.95703 10.9766L7.95996 10.9756C7.96302 10.9756 7.96666 10.9774 7.96973 10.9775Z"),
)
}.build()
return _ic_cloud_exclamation_16!!
}
@Composable
@Preview(showBackground = true)
private fun IcCloudExclamation16Preview() {
Icon(
imageVector = Icons.ic_cloud_exclamation_16,
contentDescription = null,
)
}

View file

@ -0,0 +1,57 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_cloud_exclamation_20: ImageVector? = null
val Icons.ic_cloud_exclamation_20: ImageVector
get() {
if (_ic_cloud_exclamation_20 != null) return _ic_cloud_exclamation_20!!
_ic_cloud_exclamation_20 = ImageVector.Builder(
name = "ic_cloud_exclamation_20",
defaultWidth = 20.dp,
defaultHeight = 20.dp,
viewportWidth = 20f,
viewportHeight = 20f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M10.0782 14.157C10.0851 14.1577 10.092 14.16 10.0988 14.1609C10.4048 14.1962 10.6726 14.3909 10.794 14.6794C10.9288 15.0005 10.8569 15.3719 10.6112 15.6189C10.3654 15.8659 9.99379 15.94 9.67143 15.8074C9.34935 15.6745 9.13957 15.3605 9.13947 15.0125V15.0085C9.14108 14.5534 9.4967 14.1837 9.94524 14.156C9.96157 14.1548 9.97851 14.1532 9.99511 14.1531L9.99707 14.1541L10.002 14.1531L10.0782 14.157Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M10 4.12769C12.5854 4.12769 14.7201 6.049 15.0537 8.53979C16.7327 8.86762 18 10.3441 18 12.1169C17.9998 14.1302 16.3656 15.7623 14.3496 15.7625H12.8994C12.4848 15.7623 12.1486 15.4264 12.1484 15.0125C12.1485 14.5984 12.4848 14.2626 12.8994 14.2625H14.3496C15.536 14.2623 16.4978 13.3017 16.498 12.1169C16.498 10.932 15.5361 9.97154 14.3496 9.97144C13.935 9.97144 13.5989 9.63539 13.5986 9.22144C13.5986 7.23677 11.9873 5.62769 10 5.62769C8.46025 5.62859 7.09144 6.60827 6.59602 8.06421C6.50408 8.33367 6.26742 8.52841 5.98484 8.56616C4.56533 8.75586 3.50461 9.96404 3.50202 11.3943C3.5029 12.9784 4.78956 14.2625 6.37599 14.2625H7.1006C7.51521 14.2626 7.8515 14.5984 7.85161 15.0125C7.85141 15.4264 7.51516 15.7623 7.1006 15.7625H6.37599C3.95969 15.7625 2.00036 13.8063 2 11.3933V11.3914L2.00489 11.1882C2.09806 9.24903 3.4668 7.61354 5.33749 7.16284C6.14627 5.33181 7.96814 4.12867 10 4.12769Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M10 9.3728C10.4145 9.37307 10.751 9.70875 10.751 10.1228V12.321C10.751 12.7351 10.4145 13.0708 10 13.071C9.58531 13.071 9.24901 12.7352 9.24899 12.321V10.1228C9.24899 9.70864 9.5853 9.37289 10 9.3728Z"),
)
}.build()
return _ic_cloud_exclamation_20!!
}
@Composable
@Preview(showBackground = true)
private fun IcCloudExclamation20Preview() {
Icon(
imageVector = Icons.ic_cloud_exclamation_20,
contentDescription = null,
)
}

View file

@ -0,0 +1,57 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_cloud_exclamation_24: ImageVector? = null
val Icons.ic_cloud_exclamation_24: ImageVector
get() {
if (_ic_cloud_exclamation_24 != null) return _ic_cloud_exclamation_24!!
_ic_cloud_exclamation_24 = ImageVector.Builder(
name = "ic_cloud_exclamation_24",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M12.125 17.1061C12.5311 17.151 12.887 17.4096 13.0479 17.7926C13.2257 18.2168 13.1308 18.7075 12.8066 19.0338C12.4824 19.36 11.9926 19.4579 11.5674 19.2828C11.1422 19.1075 10.8646 18.6928 10.8643 18.233V18.2281C10.8662 17.6046 11.3708 17.0995 11.9932 17.0963L11.9971 17.0973L12.0029 17.0963C12.0442 17.0965 12.0851 17.1011 12.125 17.1061Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M12 4.63147C15.2272 4.63171 17.8952 7.02079 18.335 10.1266C20.4272 10.5585 22.0007 12.4114 22.001 14.6315C22.001 17.1719 19.9408 19.2318 17.4004 19.2321H15.6006C15.0483 19.2321 14.6006 18.7843 14.6006 18.2321C14.6007 17.6798 15.0483 17.2321 15.6006 17.2321H17.4004C18.8362 17.2318 20.001 16.0673 20.001 14.6315C20.0007 13.1958 18.836 12.0321 17.4004 12.0319C16.8483 12.0318 16.4005 11.584 16.4004 11.0319C16.4003 8.6019 14.4299 6.63173 12 6.63147C10.1174 6.63275 8.44473 7.8324 7.83887 9.61487C7.71672 9.9743 7.40059 10.2332 7.02441 10.2838C5.29538 10.5151 4.00318 11.9896 4 13.734C4.00119 15.666 5.56772 17.232 7.5 17.2321H8.40039C8.95233 17.2324 9.40032 17.68 9.40039 18.2321C9.40035 18.7841 8.95235 19.2317 8.40039 19.2321H7.5C4.4625 19.232 1.99916 16.7695 1.99902 13.7321V13.7301L2.00684 13.4742C2.12336 11.0444 3.82809 8.99404 6.16309 8.41565C7.18456 6.13176 9.46143 4.63271 12 4.63147Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M12.001 11.1764C12.5528 11.1769 13.001 11.6244 13.001 12.1764V14.8981C13.001 15.45 12.5528 15.8975 12.001 15.8981C11.4487 15.8981 11.001 15.4504 11.001 14.8981V12.1764C11.001 11.6241 11.4487 11.1764 12.001 11.1764Z"),
)
}.build()
return _ic_cloud_exclamation_24!!
}
@Composable
@Preview(showBackground = true)
private fun IcCloudExclamation24Preview() {
Icon(
imageVector = Icons.ic_cloud_exclamation_24,
contentDescription = null,
)
}

View file

@ -0,0 +1,57 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_cloud_exclamation_28: ImageVector? = null
val Icons.ic_cloud_exclamation_28: ImageVector
get() {
if (_ic_cloud_exclamation_28 != null) return _ic_cloud_exclamation_28!!
_ic_cloud_exclamation_28 = ImageVector.Builder(
name = "ic_cloud_exclamation_28",
defaultWidth = 28.dp,
defaultHeight = 28.dp,
viewportWidth = 28f,
viewportHeight = 28f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M14.0142 20.0228C14.5776 20.0287 15.0848 20.3676 15.3035 20.8881C15.5251 21.4158 15.4062 22.0251 15.0024 22.431C14.5986 22.8368 13.9894 22.9597 13.4599 22.7416C12.9305 22.5233 12.5852 22.0072 12.5851 21.4349V21.4291C12.5875 20.684 13.1673 20.0771 13.8998 20.0267C13.9297 20.0244 13.9603 20.0221 13.9907 20.0219C13.9929 20.0218 13.9954 20.0228 13.9976 20.0228C13.999 20.0228 14.0009 20.0219 14.0024 20.0219L14.0142 20.0228Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M14.0005 5.15173C17.8697 5.15209 21.0714 8.00381 21.617 11.7181C24.1213 12.2542 26 14.4779 26 17.14C25.9998 20.2022 23.514 22.6847 20.4489 22.6849H18.2994C17.6085 22.6849 17.0483 22.1252 17.0483 21.4349C17.0483 20.7446 17.6085 20.185 18.2994 20.1849H20.4489C22.132 20.1847 23.4975 18.8215 23.4977 17.14C23.4977 15.4584 22.1321 14.0944 20.4489 14.0941C19.758 14.094 19.1978 13.5344 19.1977 12.8441C19.1975 10.0661 17.0134 7.7977 14.2673 7.65857L14.0005 7.65173C11.7764 7.65297 9.79943 9.06836 9.08378 11.1722C8.9309 11.6217 8.53614 11.946 8.06525 12.0092C6.02886 12.2813 4.50721 14.0152 4.50332 16.0677C4.50435 18.3417 6.34995 20.1849 8.62632 20.1849H9.70057C10.3913 20.1852 10.9517 20.7448 10.9517 21.4349C10.9517 22.1251 10.3913 22.6847 9.70057 22.6849H8.62632C4.96735 22.6849 2.00007 19.7213 2 16.0658V16.0638L2.0088 15.7552C2.14891 12.8406 4.19026 10.3802 6.98904 9.67517C8.22334 6.94406 10.9556 5.15326 14.0005 5.15173Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M13.9995 12.9252C14.6904 12.9253 15.2507 13.4849 15.2507 14.1752V17.4379C15.2507 18.1282 14.6904 18.6878 13.9995 18.6879C13.3085 18.6879 12.7483 18.1282 12.7483 17.4379V14.1752C12.7483 13.4848 13.3085 12.9252 13.9995 12.9252Z"),
)
}.build()
return _ic_cloud_exclamation_28!!
}
@Composable
@Preview(showBackground = true)
private fun IcCloudExclamation28Preview() {
Icon(
imageVector = Icons.ic_cloud_exclamation_28,
contentDescription = null,
)
}

View file

@ -0,0 +1,57 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_cloud_exclamation_32: ImageVector? = null
val Icons.ic_cloud_exclamation_32: ImageVector
get() {
if (_ic_cloud_exclamation_32 != null) return _ic_cloud_exclamation_32!!
_ic_cloud_exclamation_32 = ImageVector.Builder(
name = "ic_cloud_exclamation_32",
defaultWidth = 32.dp,
defaultHeight = 32.dp,
viewportWidth = 32f,
viewportHeight = 32f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M16.0191 22.9534C16.6496 22.9604 17.2211 23.3164 17.5057 23.8723L17.5595 23.9875L17.6045 24.1067C17.8057 24.7082 17.6522 25.3763 17.1996 25.8313C16.7167 26.3165 15.9883 26.4632 15.355 26.2024C14.722 25.9416 14.3087 25.3256 14.3085 24.6418V24.634C14.3115 23.7433 15.0057 23.0187 15.8821 22.9592C15.9176 22.9565 15.9536 22.9526 15.9897 22.9524C15.9923 22.9524 15.9949 22.9534 15.9976 22.9534L16.0034 22.9524C16.0086 22.9524 16.0139 22.9533 16.0191 22.9534Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M16.0005 5.67017C20.5125 5.67047 24.2482 8.9868 24.8996 13.3108C27.8167 13.9506 30 16.5458 30 19.6506C29.9995 23.2353 27.0892 26.1416 23.499 26.1418H20.9992C20.1697 26.1418 19.4972 25.47 19.4969 24.6418C19.497 23.8135 20.1696 23.1419 20.9992 23.1418H23.499C25.4298 23.1416 26.995 21.5785 26.9955 19.6506C26.9955 17.7224 25.4301 16.1587 23.499 16.1584C22.6695 16.1584 21.9971 15.4866 21.9968 14.6584C21.9967 11.4551 19.4768 8.83938 16.3086 8.67896L16.0005 8.67114C13.4345 8.67255 11.1545 10.3048 10.3289 12.7307C10.1452 13.2699 9.67075 13.659 9.10538 13.7346C6.76077 14.0478 5.00873 16.0436 5.00451 18.4055C5.00648 21.0213 7.13072 23.1417 9.75088 23.1418H11.0008C11.8303 23.142 12.503 23.8135 12.5031 24.6418C12.5028 25.47 11.8302 26.1417 11.0008 26.1418H9.75088C5.4704 26.1417 2.00039 22.6766 2 18.4026V18.3997L2.0088 18.0393C2.17223 14.6385 4.55082 11.7664 7.81438 10.9348C9.26176 7.75593 12.449 5.67189 16.0005 5.67017Z"),
)
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M16.0005 14.7415C16.8299 14.7417 17.5027 15.4132 17.5027 16.2415V20.0178C17.5027 20.8461 16.8299 21.5176 16.0005 21.5178C15.1708 21.5178 14.4982 20.8462 14.4982 20.0178V16.2415C14.4982 15.413 15.1708 14.7415 16.0005 14.7415Z"),
)
}.build()
return _ic_cloud_exclamation_32!!
}
@Composable
@Preview(showBackground = true)
private fun IcCloudExclamation32Preview() {
Icon(
imageVector = Icons.ic_cloud_exclamation_32,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_contact_book_16_filled: ImageVector? = null
val Icons.ic_contact_book_16_filled: ImageVector
get() {
if (_ic_contact_book_16_filled != null) return _ic_contact_book_16_filled!!
_ic_contact_book_16_filled = ImageVector.Builder(
name = "ic_contact_book_16_filled",
defaultWidth = 16.dp,
defaultHeight = 16.dp,
viewportWidth = 16f,
viewportHeight = 16f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M11.3643 2.01172C12.1353 2.08971 12.7425 2.73692 12.7432 3.53125L12.751 12.4688L12.7432 12.626C12.6641 13.3994 12.0063 13.997 11.2148 13.9971H4.79395C3.9502 13.997 3.25875 13.318 3.25781 12.4707L3.25586 11.8887H2.62793C2.28289 11.8887 2.00316 11.6087 2.00293 11.2637C2.00302 10.9186 2.28281 10.6387 2.62793 10.6387H3.25098L3.25 10.4951V8.62598H2.62793C2.28295 8.62598 2.00324 8.34589 2.00293 8.00098C2.00293 7.6558 2.28275 7.37598 2.62793 7.37598H3.25V5.36328H2.62793C2.28305 5.36328 2.00342 5.08304 2.00293 4.73828C2.00293 4.3931 2.28275 4.11328 2.62793 4.11328H3.25V3.53223L3.25879 3.375C3.33817 2.60188 3.99482 2.00398 4.78613 2.00391H11.207L11.3643 2.01172ZM7.29102 8.63574C6.59853 8.63775 6.03713 9.19911 6.03516 9.8916V10.0332C6.03525 10.2208 6.1105 10.4005 6.24316 10.5332C6.37584 10.6659 6.55554 10.7411 6.74316 10.7412H9.25684C9.64763 10.7411 9.96464 10.424 9.96484 10.0332V9.8916C9.96287 9.19909 9.4015 8.63772 8.70898 8.63574H7.29102ZM8 5.25879C7.32393 5.25895 6.77555 5.80733 6.77539 6.4834C6.77565 7.15938 7.32399 7.70785 8 7.70801C8.67606 7.70792 9.22435 7.15942 9.22461 6.4834C9.22445 5.80728 8.67613 5.25888 8 5.25879Z"),
)
}.build()
return _ic_contact_book_16_filled!!
}
@Composable
@Preview(showBackground = true)
private fun IcContactBook16FilledPreview() {
Icon(
imageVector = Icons.ic_contact_book_16_filled,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_contact_book_20_filled: ImageVector? = null
val Icons.ic_contact_book_20_filled: ImageVector
get() {
if (_ic_contact_book_20_filled != null) return _ic_contact_book_20_filled!!
_ic_contact_book_20_filled = ImageVector.Builder(
name = "ic_contact_book_20_filled",
defaultWidth = 20.dp,
defaultHeight = 20.dp,
viewportWidth = 20f,
viewportHeight = 20f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M13.8491 3.00195C15.031 3.00195 15.9994 3.95451 15.9995 5.1416V14.8623C15.9992 16.0493 15.0309 17.001 13.8491 17.001H6.1499C4.96831 17.0007 3.99978 16.0491 3.99951 14.8623V14.3857H3.24951C2.83552 14.3855 2.49951 14.0498 2.49951 13.6357C2.49989 13.222 2.83576 12.886 3.24951 12.8857H3.99951V10.749H3.24951C2.83552 10.7488 2.49951 10.4131 2.49951 9.99902C2.49997 9.58536 2.8358 9.24929 3.24951 9.24902H3.99951V7.11328H3.24951C2.83552 7.11302 2.49951 6.77733 2.49951 6.36328C2.49978 5.94946 2.83569 5.61354 3.24951 5.61328H3.99951V5.1416C3.99962 3.95467 4.96822 3.00221 6.1499 3.00195H13.8491ZM9.00732 10.5605C8.09866 10.5634 7.35222 11.2537 7.26025 12.1387L7.25049 12.3174V12.5156C7.2506 12.7783 7.35477 13.031 7.54053 13.2168C7.72634 13.4023 7.97909 13.5068 8.2417 13.5068H11.7593C12.3063 13.5066 12.7503 13.0626 12.7505 12.5156V12.3174C12.7477 11.4089 12.0571 10.6625 11.1724 10.5703L10.9937 10.5605H9.00732ZM9.99951 6.49316C9.0533 6.49344 8.28605 7.26085 8.28564 8.20703C8.28564 9.15356 9.05305 9.9216 9.99951 9.92188C10.9462 9.92188 11.7144 9.15372 11.7144 8.20703C11.7139 7.26069 10.946 6.49316 9.99951 6.49316Z"),
)
}.build()
return _ic_contact_book_20_filled!!
}
@Composable
@Preview(showBackground = true)
private fun IcContactBook20FilledPreview() {
Icon(
imageVector = Icons.ic_contact_book_20_filled,
contentDescription = null,
)
}

View file

@ -0,0 +1,47 @@
@file:Suppress("all")
package com.tangem.core.ui.res.generated.icons
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
/**
* Auto-generated from design tokens. Do not edit manually.
*/
private var _ic_contact_book_24_filled: ImageVector? = null
val Icons.ic_contact_book_24_filled: ImageVector
get() {
if (_ic_contact_book_24_filled != null) return _ic_contact_book_24_filled!!
_ic_contact_book_24_filled = ImageVector.Builder(
name = "ic_contact_book_24_filled",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 24f,
viewportHeight = 24f,
).apply {
addPath(
fill = SolidColor(Color.Black),
pathFillType = PathFillType.NonZero,
pathData = addPathNodes("M17.2129 3.01367C18.5081 3.14732 19.4998 4.25745 19.5 5.58301V18.417C19.4996 19.8307 18.3715 20.9999 16.9502 21H7.0498C5.62854 20.9999 4.50043 19.8307 4.5 18.417V17.8945H3C2.44797 17.8945 2.00041 17.4465 2 16.8945C2 16.3422 2.44772 15.8945 3 15.8945H4.5V12.9844H3C2.44781 12.9844 2.00015 12.5365 2 11.9844C2 11.4321 2.44772 10.9844 3 10.9844H4.5V8.0752H3C2.44781 8.0752 2.00015 7.62735 2 7.0752C2 6.52291 2.44772 6.0752 3 6.0752H4.5V5.58301C4.50017 4.16912 5.62838 2.99913 7.0498 2.99902H16.9502L17.2129 3.01367ZM10.6104 12.8867C9.49218 12.8899 8.57322 13.7392 8.45996 14.8281L8.44824 15.0488V15.3252C8.44831 15.6136 8.56268 15.8908 8.7666 16.0947C8.97055 16.2985 9.24782 16.4131 9.53613 16.4131H14.4648C15.0652 16.4128 15.5516 15.9256 15.5518 15.3252V15.0488C15.5486 13.9309 14.6999 13.012 13.6113 12.8984L13.3896 12.8867H10.6104ZM12 7.58789C10.8399 7.58798 9.8995 8.52839 9.89941 9.68848C9.8996 10.8485 10.84 11.789 12 11.7891C13.16 11.789 14.1004 10.8485 14.1006 9.68848C14.1005 8.52839 13.1601 7.58798 12 7.58789Z"),
)
}.build()
return _ic_contact_book_24_filled!!
}
@Composable
@Preview(showBackground = true)
private fun IcContactBook24FilledPreview() {
Icon(
imageVector = Icons.ic_contact_book_24_filled,
contentDescription = null,
)
}

Some files were not shown because too many files have changed in this diff Show more