Updated on 2026-08-14

This commit is contained in:
Tangem 2025-12-23 15:12:48 +05:00
parent a94abd2a39
commit 6f095384c1
10 changed files with 481 additions and 10 deletions

View file

@ -48,6 +48,21 @@ fun Modifier.conditional(condition: Boolean, modifier: Modifier.() -> Modifier):
}
}
/**
* Conditionally applies a modifier based on a boolean condition.
*/
@Composable
fun Modifier.conditionalCompose(
condition: Boolean,
modifier: @Composable Modifier.() -> Modifier = { Modifier },
): Modifier {
return if (condition) {
then(modifier(Modifier))
} else {
this
}
}
/**
* Conditionally applies a modifier based on a boolean condition.
*/

View file

@ -18,6 +18,18 @@ object TangemColorPalette {
val Dark6 = Color(0xFF1E1E1E)
// endregion Dark
// region Dark Alpha
val Dark_10 = Color(0x1A1E1E1E)
val Dark_20 = Color(0x331E1E1E)
val Dark_30 = Color(0x4D1E1E1E)
val Dark_40 = Color(0x661E1E1E)
val Dark_50 = Color(0x801E1E1E)
val Dark_60 = Color(0x991E1E1E)
val Dark_70 = Color(0xB31E1E1E)
val Dark_80 = Color(0xCC1E1E1E)
val Dark_90 = Color(0xE61E1E1E)
// endregion Dark Alpha
// region Light
val Light1 = Color(0xFFF5F5F5)
val Light1V2 = Color(0xFFF4F4F4)
@ -27,6 +39,18 @@ object TangemColorPalette {
val Light5 = Color(0xFFB0B0B0)
// endregion Light
// region Light Alpha
val Light_10 = Color(0x1AFFFFFF)
val Light_20 = Color(0x33FFFFFF)
val Light_30 = Color(0x4DFFFFFF)
val Light_40 = Color(0x66FFFFFF)
val Light_50 = Color(0x80FFFFFF)
val Light_60 = Color(0x99FFFFFF)
val Light_70 = Color(0xB3FFFFFF)
val Light_80 = Color(0xCCFFFFFF)
val Light_90 = Color(0xE6FFFFFF)
// endregion Light Alpha
// region Green
val Green = Color(0xFF0C9F3D)
val Meadow = Color(0xFF1ACE80)

View file

@ -162,6 +162,7 @@ class TangemColors2 internal constructor(
backgroundSecondary: Color,
backgroundDisabled: Color,
backgroundPositive: Color,
backgroundPrimaryInverse: Color,
textPrimary: Color,
textSecondary: Color,
textDisabled: Color,
@ -178,6 +179,8 @@ class TangemColors2 internal constructor(
private set
var backgroundPositive by mutableStateOf(backgroundPositive)
private set
var backgroundPrimaryInverse by mutableStateOf(backgroundPrimaryInverse)
private set
var textPrimary by mutableStateOf(textPrimary)
private set
var textSecondary by mutableStateOf(textSecondary)
@ -198,6 +201,7 @@ class TangemColors2 internal constructor(
backgroundSecondary = other.backgroundSecondary
backgroundDisabled = other.backgroundDisabled
backgroundPositive = other.backgroundPositive
backgroundPrimaryInverse = other.backgroundPrimaryInverse
textPrimary = other.textPrimary
textSecondary = other.textSecondary
textDisabled = other.textDisabled

View file

@ -0,0 +1,39 @@
package com.tangem.core.ui.res
import androidx.compose.runtime.Immutable
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@Suppress("ConstructorParameterNaming")
@ConsistentCopyVisibility
@Immutable
data class TangemDimens2 internal constructor(
val x0: Dp = 0.dp,
val x0_5: Dp = 2.dp,
val x1: Dp = 4.dp,
val x2: Dp = 8.dp,
val x2_5: Dp = 10.dp,
val x3: Dp = 12.dp,
val x4: Dp = 16.dp,
val x5: Dp = 20.dp,
val x6: Dp = 24.dp,
val x7: Dp = 28.dp,
val x8: Dp = 32.dp,
val x9: Dp = 36.dp,
val x10: Dp = 40.dp,
val x11: Dp = 44.dp,
val x12: Dp = 48.dp,
val x13: Dp = 52.dp,
val x14: Dp = 56.dp,
val x15: Dp = 60.dp,
val x16: Dp = 64.dp,
val x17: Dp = 68.dp,
val x18: Dp = 72.dp,
val x19: Dp = 76.dp,
val x20: Dp = 80.dp,
val x21: Dp = 84.dp,
val x22: Dp = 88.dp,
val x23: Dp = 92.dp,
val x24: Dp = 96.dp,
val x25: Dp = 100.dp,
)

View file

@ -154,11 +154,21 @@ object TangemTheme {
@ReadOnlyComposable
get() = LocalTangemTypography.current
val typography2: TangemTypography2
@Composable
@ReadOnlyComposable
get() = TangemTypography2(InterFamily)
val dimens: TangemDimens
@Composable
@ReadOnlyComposable
get() = LocalTangemDimens.current
val dimens2: TangemDimens2
@Composable
@ReadOnlyComposable
get() = LocalTangemDimens2.current
val shapes: TangemShapes
@Composable
@ReadOnlyComposable
@ -343,10 +353,18 @@ internal val LocalTangemTypography = staticCompositionLocalOf {
TangemTypography(RobotoFamily)
}
internal val LocalTangemTypography2 = staticCompositionLocalOf {
TangemTypography2(InterFamily)
}
private val LocalTangemDimens = staticCompositionLocalOf {
TangemDimens()
}
private val LocalTangemDimens2 = staticCompositionLocalOf {
TangemDimens2()
}
private val LocalTangemShapes = staticCompositionLocalOf<TangemShapes> {
error("No TangemShapes provided")
}

View file

@ -37,6 +37,32 @@ fun TangemThemePreview(
}
}
@Composable
fun TangemThemePreviewRedesign(
isDark: Boolean? = null,
alwaysShowBottomSheets: Boolean = true,
rtl: Boolean = false,
content: @Composable () -> Unit,
) {
val isDarkTheme = isDark ?: isSystemInDarkTheme()
CompositionLocalProvider(
LocalBottomSheetAlwaysVisible provides alwaysShowBottomSheets,
LocalLayoutDirection provides if (rtl) LayoutDirection.Rtl else LayoutDirection.Ltr,
) {
BoxWithConstraints {
TangemTheme(
isDark = isDarkTheme,
windowSize = rememberWindowSizePreview(maxWidth, maxHeight),
) {
TangemThemeRedesign(
content = content,
)
}
}
}
}
/**
* This is used to make the bottom sheet always visible in the Preview and should be `true` only in the Preview.
* */

View file

@ -1,4 +1,5 @@
@file:Suppress("LongMethod")
package com.tangem.core.ui.res
import androidx.compose.material3.MaterialTheme
@ -22,7 +23,7 @@ fun TangemThemeRedesign(content: @Composable () -> Unit) {
CompositionLocalProvider(
LocalTangemColors provides themeColors,
LocalTangemColors2 provides if (LocalIsInDarkTheme.current) darkThemeColors2() else lightThemeColors2(),
LocalTangemTypography provides TangemTypography(InterFamily),
LocalTangemTypography2 provides TangemTypography2(InterFamily),
LocalRootBackgroundColor provides remember(rootBackgroundColor) { mutableStateOf(rootBackgroundColor) },
) {
content()
@ -97,9 +98,10 @@ private fun lightThemeColors2(): TangemColors2 {
)
val button = TangemColors2.Button(
backgroundPrimary = TangemColorPalette.Dark6,
backgroundSecondary = TangemColorPalette.Dark6.copy(alpha = 0.1f),
backgroundSecondary = TangemColorPalette.Dark_10,
backgroundDisabled = TangemColorPalette.Light3,
backgroundPositive = TangemColorPalette.Azure,
backgroundPrimaryInverse = TangemColorPalette.White,
textSecondary = TangemColorPalette.Dark6,
textPrimary = TangemColorPalette.Light2,
textDisabled = text.neutral.tertiary,
@ -236,9 +238,10 @@ private fun darkThemeColors2(): TangemColors2 {
)
val button = TangemColors2.Button(
backgroundPrimary = TangemColorPalette.Light1V2,
backgroundSecondary = TangemColorPalette.White.copy(alpha = 0.1f),
backgroundSecondary = TangemColorPalette.Light_10,
backgroundDisabled = TangemColorPalette.Dark5,
backgroundPositive = TangemColorPalette.Azure,
backgroundPrimaryInverse = TangemColorPalette.Light_10,
textSecondary = TangemColorPalette.Light4,
textPrimary = TangemColorPalette.Dark4,
textDisabled = text.neutral.secondary,

View file

@ -4,7 +4,6 @@ import androidx.compose.runtime.Immutable
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.LineHeightStyle
import androidx.compose.ui.unit.TextUnit
@ -17,11 +16,6 @@ internal val RobotoFamily = FontFamily(
Font(R.font.roboto_medium, FontWeight.Medium),
)
internal val InterFamily = FontFamily(
Font(R.font.inter_regular),
Font(R.font.inter_italic, style = FontStyle.Italic),
)
@Immutable
class TangemTypography internal constructor(
fontFamily: FontFamily,

View file

@ -0,0 +1,348 @@
package com.tangem.core.ui.res
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.LineHeightStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.tangem.core.ui.R
internal val InterFamily = FontFamily(
Font(R.font.inter_regular),
Font(R.font.inter_italic, style = FontStyle.Italic),
)
@Stable
class TangemTypography2 internal constructor(
fontFamily: FontFamily,
) {
val titleRegular44: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 44.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = 0.37f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 48f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingRegular34: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 34.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = 0.37f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 40f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingBold34: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 34.sp,
fontWeight = FontWeight.Bold,
letterSpacing = TextUnit(value = 0.37f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 40f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingRegular28: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 28.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = 0.36f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 36f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingBold28: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 28.sp,
fontWeight = FontWeight.Bold,
letterSpacing = TextUnit(value = 0.36f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 36f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingRegular22: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 22.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = 0.35f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 28f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingBold22: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 22.sp,
fontWeight = FontWeight.Bold,
letterSpacing = TextUnit(value = 0.35f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 28f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingRegular20: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 20.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = 0.38f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 24f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingSemibold20: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 20.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = 0.38f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 24f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingRegular17: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 17.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = -0.41f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 20f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingSemibold17: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 17.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = -0.2f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 20f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val bodyRegular16: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 16.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = -0.32f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 20f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val bodySemibold16: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 16.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = -0.32f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 20f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val bodyRegular15: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 15.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = -0.24f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 20f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val bodySemibold15: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 15.sp,
fontWeight = FontWeight.Medium,
letterSpacing = TextUnit(value = -0.1f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 20f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val bodyRegular14: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
letterSpacing = TextUnit(value = -0.1f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 16f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val captionRegular13: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 13.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = -0.08f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 16f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val captionSemibold13: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 13.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = 0.1f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 16f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val captionRegular12: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 12.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = 0f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 16f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val captionSemibold12: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
letterSpacing = TextUnit(value = 0.1f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 16f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val captionRegular11: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 11.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = 0.07f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 12f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val captionSemibold11: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 11.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = 0.15f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 12f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 360, heightDp = 1500)
@Preview(showBackground = true, widthDp = 360, heightDp = 1500, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun TangemTypography2_Preview() {
TangemThemePreviewRedesign {
val typographyList = sequenceOf(
TangemTheme.typography2.titleRegular44,
TangemTheme.typography2.headingRegular34,
TangemTheme.typography2.headingBold34,
TangemTheme.typography2.headingRegular28,
TangemTheme.typography2.headingBold28,
TangemTheme.typography2.headingRegular22,
TangemTheme.typography2.headingBold22,
TangemTheme.typography2.headingRegular20,
TangemTheme.typography2.headingSemibold20,
TangemTheme.typography2.headingRegular17,
TangemTheme.typography2.headingSemibold17,
TangemTheme.typography2.bodyRegular16,
TangemTheme.typography2.bodySemibold16,
TangemTheme.typography2.bodyRegular15,
TangemTheme.typography2.bodySemibold15,
TangemTheme.typography2.bodyRegular14,
TangemTheme.typography2.captionRegular13,
TangemTheme.typography2.captionSemibold13,
TangemTheme.typography2.captionRegular12,
TangemTheme.typography2.captionSemibold12,
TangemTheme.typography2.captionRegular11,
TangemTheme.typography2.captionSemibold11,
)
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.background(TangemTheme.colors2.surface.level1)
.padding(4.dp),
) {
typographyList.forEach { textStyle ->
Box(modifier = Modifier.heightIn(min = 60.dp)) {
Text(
text = "Lorem ipsum",
style = textStyle,
color = TangemTheme.colors2.text.neutral.primary,
modifier = Modifier.align(Alignment.Center),
)
}
}
}
}
}
// endregion

@ -1 +1 @@
Subproject commit d7950d60bb4c6353f2aa3364073c6ec72167c666
Subproject commit fa10299aec0b3a06fda9bf6d050e0aa79609d33b