From db9ec70213ac3f05a4bf1b622bb58f2f48a8464a Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 8 Jun 2026 19:11:28 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/core/ui/ds2/badge/TangemBadge.kt | 29 +++-- .../tangem/core/ui/ds2/button/TangemButton.kt | 6 +- .../ui/ds2/button/TangemButtonInternal.kt | 93 ++++++++------- .../com/tangem/core/ui/ds2/row/TangemRow.kt | 18 +-- .../tangem/core/ui/ds2/search/TangemSearch.kt | 16 +-- .../core/ui/ds2/surface/TangemSurface.kt | 6 +- .../ds2/topnavigation/TangemTopNavigation.kt | 16 +-- .../com/tangem/core/ui/res/TangemTheme.kt | 10 -- .../tangem/core/ui/res/TangemThemeRedesign.kt | 3 - .../core/ui/res/generated/TangemDimens3.kt | 110 ------------------ core/ui/token-gen/README.md | 15 ++- core/ui/token-gen/build-tokens.mjs | 104 +---------------- .../tangempay/ui/TangempayTxDetailsUiV2.kt | 3 +- .../ui/components/TangemPayCardView.kt | 6 +- .../page/ds/shimmer/TangemShimmerStory.kt | 8 +- 15 files changed, 115 insertions(+), 328 deletions(-) delete mode 100644 core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemDimens3.kt diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds2/badge/TangemBadge.kt b/core/ui/src/main/java/com/tangem/core/ui/ds2/badge/TangemBadge.kt index 9d7cbf9a37..67ac1a5ad2 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/ds2/badge/TangemBadge.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/ds2/badge/TangemBadge.kt @@ -87,8 +87,8 @@ fun TangemBadge( .heightIn(min = sizeTokens.minHeight), onClick = onClick, color = colorTokens.backgroundColor, - border = colorTokens.borderColor?.let { BorderStroke(TangemTheme.dimens3.borderWidth.sm, it) }, - shape = RoundedCornerShape(TangemTheme.dimens3.borderRadius.full), + border = colorTokens.borderColor?.let { BorderStroke(1.dp, it) }, + shape = RoundedCornerShape(999.dp), ) { BadgeContent( iconStart = iconStart, @@ -206,30 +206,29 @@ private data class BadgeSizeTokens( @Composable @ReadOnlyComposable private fun TangemBadge.Size.tokens(): BadgeSizeTokens { - val dimens = TangemTheme.dimens3 val typography = TangemTheme.typography3 return when (this) { TangemBadge.Size.X9 -> BadgeSizeTokens( - minHeight = dimens.size.s450, - containerHorizontalPadding = dimens.spacing.s100, - containerVerticalPadding = dimens.spacing.s100, - labelPadding = dimens.spacing.s050, + minHeight = 36.dp, + containerHorizontalPadding = 8.dp, + containerVerticalPadding = 8.dp, + labelPadding = 4.dp, iconSize = 20.dp, textStyle = typography.subheading.medium, ) TangemBadge.Size.X6 -> BadgeSizeTokens( - minHeight = dimens.size.s300, - containerHorizontalPadding = dimens.spacing.s050, - containerVerticalPadding = dimens.spacing.s050, - labelPadding = dimens.spacing.s050, + minHeight = 24.dp, + containerHorizontalPadding = 4.dp, + containerVerticalPadding = 4.dp, + labelPadding = 4.dp, iconSize = 16.dp, textStyle = typography.caption.medium, ) TangemBadge.Size.X4 -> BadgeSizeTokens( - minHeight = dimens.size.s200, - containerHorizontalPadding = dimens.spacing.s025, - containerVerticalPadding = dimens.spacing.none, - labelPadding = dimens.spacing.s025, + minHeight = 16.dp, + containerHorizontalPadding = 2.dp, + containerVerticalPadding = 0.dp, + labelPadding = 2.dp, iconSize = 12.dp, textStyle = typography.caption.medium, ) diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds2/button/TangemButton.kt b/core/ui/src/main/java/com/tangem/core/ui/ds2/button/TangemButton.kt index 72af200875..4dce68a7c7 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/ds2/button/TangemButton.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/ds2/button/TangemButton.kt @@ -108,7 +108,7 @@ fun TangemButton( enabled = isEnabled, color = backgroundColor, border = resolveBorder(isFocused = isFocused, colorTokens = colorTokens, contentAlpha = contentAlpha), - shape = RoundedCornerShape(TangemTheme.dimens3.borderRadius.full), + shape = RoundedCornerShape(999.dp), interactionSource = interactionSource, isMaterial = variant == TangemButton.Variant.Material, ) { @@ -129,12 +129,12 @@ fun TangemButton( @Composable private fun resolveBorder(isFocused: Boolean, colorTokens: ColorTokens, contentAlpha: Float): BorderStroke? = when { isFocused -> BorderStroke( - width = TangemTheme.dimens3.borderWidth.md, + width = 2.dp, // Focus ring is intentionally NOT scaled by contentAlpha — see TangemButton above. color = colorTokens.focusRingColor, ) colorTokens.defaultBorderColor != null -> BorderStroke( - width = TangemTheme.dimens3.borderWidth.sm, + width = 1.dp, color = colorTokens.defaultBorderColor.scaleAlpha(contentAlpha), ) else -> null diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds2/button/TangemButtonInternal.kt b/core/ui/src/main/java/com/tangem/core/ui/ds2/button/TangemButtonInternal.kt index 3a0d23d4b8..6ab5a5c86f 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/ds2/button/TangemButtonInternal.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/ds2/button/TangemButtonInternal.kt @@ -282,7 +282,7 @@ internal fun TangemButton.Variant.tokens(): ColorTokens { disabledTextColor = TangemTheme.colors3.text.primary, disabledIconTint = TangemTheme.colors3.icon.primary, focusRingColor = TangemTheme.colors3.interaction.focusRing.brand, - disabledAlpha = TangemTheme.dimens3.opacity.disabled, + disabledAlpha = 0.4f, ) TangemButton.Variant.Material -> ColorTokens( // Background is the haze fill (FILL/MATERIAL) rendered by TangemSurface when isMaterial = true; @@ -303,7 +303,7 @@ internal fun TangemButton.Variant.tokens(): ColorTokens { disabledTextColor = TangemTheme.colors3.text.staticDark.primary, disabledIconTint = TangemTheme.colors3.icon.staticDark, focusRingColor = TangemTheme.colors3.interaction.focusRing.default, - disabledAlpha = TangemTheme.dimens3.opacity.disabled, + disabledAlpha = 0.4f, ) TangemButton.Variant.Outline -> ColorTokens( backgroundColor = Color.Transparent, @@ -313,7 +313,7 @@ internal fun TangemButton.Variant.tokens(): ColorTokens { disabledTextColor = TangemTheme.colors3.text.primary, disabledIconTint = TangemTheme.colors3.icon.primary, focusRingColor = TangemTheme.colors3.interaction.focusRing.brand, - disabledAlpha = TangemTheme.dimens3.opacity.disabled, + disabledAlpha = 0.4f, defaultBorderColor = TangemTheme.colors3.border.secondary, ) TangemButton.Variant.Ghost -> ColorTokens( @@ -324,7 +324,7 @@ internal fun TangemButton.Variant.tokens(): ColorTokens { disabledTextColor = TangemTheme.colors3.text.primary, disabledIconTint = TangemTheme.colors3.icon.primary, focusRingColor = TangemTheme.colors3.interaction.focusRing.brand, - disabledAlpha = TangemTheme.dimens3.opacity.disabled, + disabledAlpha = 0.4f, ) } } @@ -343,69 +343,68 @@ internal data class SizeTokens( @Composable @ReadOnlyComposable internal fun TangemButton.Size.tokens(): SizeTokens { - val dimens = TangemTheme.dimens3 return when (this) { TangemButton.Size.X14 -> SizeTokens( - minHeight = dimens.size.s700, - minWidth = dimens.size.s1100, - minSizeIconOnly = dimens.size.s700, - textPadding = dimens.spacing.s100, - containerHorizontalPadding = dimens.spacing.s200, - containerVerticalPadding = dimens.spacing.s200, + minHeight = 56.dp, + minWidth = 88.dp, + minSizeIconOnly = 56.dp, + textPadding = 8.dp, + containerHorizontalPadding = 16.dp, + containerVerticalPadding = 16.dp, iconSize = 24.dp, ) TangemButton.Size.X12 -> SizeTokens( - minHeight = dimens.size.s600, - minWidth = dimens.size.s1000, - minSizeIconOnly = dimens.size.s600, - textPadding = dimens.spacing.s100, - containerHorizontalPadding = dimens.spacing.s150, - containerVerticalPadding = dimens.spacing.s150, + minHeight = 48.dp, + minWidth = 80.dp, + minSizeIconOnly = 48.dp, + textPadding = 8.dp, + containerHorizontalPadding = 12.dp, + containerVerticalPadding = 12.dp, iconSize = 24.dp, ) TangemButton.Size.X11 -> SizeTokens( - minHeight = dimens.size.s550, - minWidth = dimens.size.s900, - minSizeIconOnly = dimens.size.s550, - textPadding = dimens.spacing.s075, - containerHorizontalPadding = dimens.spacing.s150, - containerVerticalPadding = dimens.spacing.s150, + minHeight = 44.dp, + minWidth = 72.dp, + minSizeIconOnly = 44.dp, + textPadding = 6.dp, + containerHorizontalPadding = 12.dp, + containerVerticalPadding = 12.dp, iconSize = 20.dp, ) TangemButton.Size.X10 -> SizeTokens( - minHeight = dimens.size.s500, - minWidth = dimens.size.s800, - minSizeIconOnly = dimens.size.s500, - textPadding = dimens.spacing.s075, - containerHorizontalPadding = dimens.spacing.s125, - containerVerticalPadding = dimens.spacing.s125, + minHeight = 40.dp, + minWidth = 64.dp, + minSizeIconOnly = 40.dp, + textPadding = 6.dp, + containerHorizontalPadding = 10.dp, + containerVerticalPadding = 10.dp, iconSize = 20.dp, ) TangemButton.Size.X9 -> SizeTokens( - minHeight = dimens.size.s450, - minWidth = dimens.size.s700, - minSizeIconOnly = dimens.size.s450, - textPadding = dimens.spacing.s075, - containerHorizontalPadding = dimens.spacing.s100, - containerVerticalPadding = dimens.spacing.s100, + minHeight = 36.dp, + minWidth = 56.dp, + minSizeIconOnly = 36.dp, + textPadding = 6.dp, + containerHorizontalPadding = 8.dp, + containerVerticalPadding = 8.dp, iconSize = 20.dp, ) TangemButton.Size.X8 -> SizeTokens( - minHeight = dimens.size.s400, - minWidth = dimens.size.s600, - minSizeIconOnly = dimens.size.s400, - textPadding = dimens.spacing.s075, - containerHorizontalPadding = dimens.spacing.s075, - containerVerticalPadding = dimens.spacing.s075, + minHeight = 32.dp, + minWidth = 48.dp, + minSizeIconOnly = 32.dp, + textPadding = 6.dp, + containerHorizontalPadding = 6.dp, + containerVerticalPadding = 6.dp, iconSize = 20.dp, ) TangemButton.Size.X7 -> SizeTokens( - minHeight = dimens.size.s350, - minWidth = dimens.size.s500, - minSizeIconOnly = dimens.size.s350, - textPadding = dimens.spacing.s075, - containerHorizontalPadding = dimens.spacing.s075, - containerVerticalPadding = dimens.spacing.s050, + minHeight = 28.dp, + minWidth = 40.dp, + minSizeIconOnly = 28.dp, + textPadding = 6.dp, + containerHorizontalPadding = 6.dp, + containerVerticalPadding = 4.dp, iconSize = 16.dp, ) } diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds2/row/TangemRow.kt b/core/ui/src/main/java/com/tangem/core/ui/ds2/row/TangemRow.kt index 28f729c8cd..c87f226c6d 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/ds2/row/TangemRow.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/ds2/row/TangemRow.kt @@ -139,12 +139,12 @@ fun TangemRow( .conditionalCompose(divider) { bottomDivider( color = TangemTheme.colors3.border.secondary, - width = TangemTheme.dimens3.borderWidth.sm, - horizontalInset = TangemTheme.dimens3.spacing.s200, + width = 1.dp, + horizontalInset = 16.dp, ) } .conditionalCompose(includeInnerPaddings) { - padding(TangemTheme.dimens3.spacing.s200) + padding(16.dp) }, ) { Row( @@ -164,7 +164,7 @@ fun TangemRow( SideSlot(slot = endSlot, position = SideSlotPosition.End) } if (extraBottomSlot != null) { - SpacerH(TangemTheme.dimens3.spacing.s100) + SpacerH(8.dp) extraBottomSlot() } } @@ -202,7 +202,7 @@ private enum class SideSlotPosition { Start, End } @Composable private fun SideSlot(slot: (@Composable BoxScope.() -> Unit)?, position: SideSlotPosition) { if (slot == null) return - val spacing = TangemTheme.dimens3.spacing.s150 + val spacing = 12.dp val padding = when (position) { SideSlotPosition.Start -> Modifier.padding(end = spacing) SideSlotPosition.End -> Modifier.padding(start = spacing) @@ -297,7 +297,7 @@ private fun LabelColumnContent( alignment: Alignment.Horizontal, ) { Column( - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens3.spacing.s025), + verticalArrangement = Arrangement.spacedBy(2.dp), horizontalAlignment = alignment, ) { if (primary != null) LabelRow(alignment = alignment, content = primary) @@ -309,7 +309,7 @@ private fun LabelColumnContent( private fun LabelRow(alignment: Alignment.Horizontal, content: @Composable RowScope.() -> Unit) { Row( horizontalArrangement = Arrangement.spacedBy( - space = TangemTheme.dimens3.spacing.s050, + space = 4.dp, alignment = alignment, ), content = content, @@ -399,10 +399,10 @@ private fun rowTextAlign(role: TangemRowTextRole): TextAlign = when (role) { @Composable private fun Modifier.focusBorder(): Modifier { - val radius = TangemTheme.dimens3.borderRadius.b200 + val radius = 16.dp val shape = remember(radius) { RoundedCornerShape(radius) } return border( - width = TangemTheme.dimens3.borderWidth.md, + width = 2.dp, color = TangemTheme.colors3.interaction.focusRing.default, shape = shape, ) diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds2/search/TangemSearch.kt b/core/ui/src/main/java/com/tangem/core/ui/ds2/search/TangemSearch.kt index eb1bdad170..9dad055473 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/ds2/search/TangemSearch.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/ds2/search/TangemSearch.kt @@ -88,7 +88,7 @@ fun TangemSearch( TangemSurface( modifier = Modifier .weight(1f) - .heightIn(min = TangemTheme.dimens3.size.s550), + .heightIn(min = 44.dp), isMaterial = true, shape = CircleShape, onClick = focusRequester::requestFocus, @@ -131,14 +131,14 @@ private fun SearchField(state: TangemSearch.State, focusRequester: FocusRequeste modifier = Modifier .weight(1f) .padding( - start = TangemTheme.dimens3.spacing.s150, - top = TangemTheme.dimens3.spacing.s150, - bottom = TangemTheme.dimens3.spacing.s150, + start = 12.dp, + top = 12.dp, + bottom = 12.dp, ), verticalAlignment = Alignment.CenterVertically, ) { Icon( - modifier = Modifier.padding(end = TangemTheme.dimens3.spacing.s100), + modifier = Modifier.padding(end = 8.dp), imageVector = Icons.ic_search_20, tint = TangemTheme.colors3.icon.primary, contentDescription = null, @@ -203,7 +203,7 @@ private fun QueryTextField(state: TangemSearch.State, focusRequester: FocusReque Box { if (state.query.isEmpty()) { Text( - modifier = Modifier.padding(end = TangemTheme.dimens3.spacing.s250), + modifier = Modifier.padding(end = 20.dp), text = placeholder, style = sharedTextStyle, color = TangemTheme.colors3.text.secondary, @@ -220,7 +220,7 @@ private fun QueryTextField(state: TangemSearch.State, focusRequester: FocusReque @Composable private fun ClearButton(onClick: () -> Unit) { TangemButton( - modifier = Modifier.padding(end = TangemTheme.dimens3.spacing.s050), + modifier = Modifier.padding(end = 4.dp), size = TangemButton.Size.X9, variant = TangemButton.Variant.Ghost, iconStart = TangemIconUM.Icon(Icons.ic_cross_circle_20_filled), @@ -233,7 +233,7 @@ private fun CloseButton(onClick: () -> Unit) { val keyboardController = LocalSoftwareKeyboardController.current val focusManager = LocalFocusManager.current TangemButton( - modifier = Modifier.padding(start = TangemTheme.dimens3.spacing.s100), + modifier = Modifier.padding(start = 8.dp), size = TangemButton.Size.X11, variant = TangemButton.Variant.Material, iconStart = TangemIconUM.Icon(Icons.ic_cross_20), diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds2/surface/TangemSurface.kt b/core/ui/src/main/java/com/tangem/core/ui/ds2/surface/TangemSurface.kt index 126d853eb8..8cc5f9c678 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/ds2/surface/TangemSurface.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/ds2/surface/TangemSurface.kt @@ -62,7 +62,7 @@ fun TangemSurface( color: Color = TangemTheme.colors3.bg.primary, isMaterial: Boolean = false, border: BorderStroke? = null, - shape: Shape = RoundedCornerShape(TangemTheme.dimens3.borderRadius.b200), + shape: Shape = RoundedCornerShape(16.dp), onClick: (() -> Unit)? = null, enabled: Boolean = true, interactionSource: MutableInteractionSource? = null, @@ -123,7 +123,7 @@ private fun Modifier.materialShadow(shape: Shape): Modifier = softLayerShadow( /** Diagonal gradient stroke that wraps the material variant. */ @Composable private fun Modifier.materialBorder(shape: Shape): Modifier = border( - width = TangemTheme.dimens3.borderWidth.sm, + width = 1.dp, brush = materialBorderBrush(), shape = shape, ) @@ -145,7 +145,7 @@ private fun Modifier.materialFill(): Modifier { val hazed = hazeEffectTangem( style = HazeStyle( backgroundColor = TangemTheme.colors3.material.fill.blur, - blurRadius = TangemTheme.dimens3.blur.Button, + blurRadius = 32.dp, tints = emptyList(), ), ) { diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds2/topnavigation/TangemTopNavigation.kt b/core/ui/src/main/java/com/tangem/core/ui/ds2/topnavigation/TangemTopNavigation.kt index 0e5f09c0b7..14c26f0864 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/ds2/topnavigation/TangemTopNavigation.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/ds2/topnavigation/TangemTopNavigation.kt @@ -84,16 +84,16 @@ fun TangemTopNavigation( blur = blurBackground, ) - val groupSpacing = TangemTheme.dimens3.spacing.s100 + val groupSpacing = 8.dp Layout( modifier = Modifier .fillMaxWidth() .windowInsetsPadding(windowInsets) .padding( - top = TangemTheme.dimens3.spacing.s100, - bottom = TangemTheme.dimens3.spacing.s200, - start = TangemTheme.dimens3.spacing.s200, - end = TangemTheme.dimens3.spacing.s200, + top = 8.dp, + bottom = 16.dp, + start = 16.dp, + end = 16.dp, ), content = { // Each optional slot caches its last non-null content so the spring exit transition @@ -110,7 +110,7 @@ fun TangemTopNavigation( Column( modifier = Modifier - .padding(horizontal = TangemTheme.dimens3.spacing.s150) + .padding(horizontal = 12.dp) .layoutId(SlotId.Content), horizontalAlignment = when (contentAlign) { TangemTopNavigation.ContentAlign.Start -> Alignment.Start @@ -130,7 +130,7 @@ fun TangemTopNavigation( displayedGroup?.let { group -> TangemSurface(isMaterial = true, shape = CircleShape) { Row( - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens3.spacing.s050), + horizontalArrangement = Arrangement.spacedBy(4.dp), content = group, ) } @@ -307,7 +307,7 @@ private fun ColumnScope.TitleSubtitle(title: TextReference, subtitle: TextRefere ) { displayedSubtitle?.let { text -> Column { - Spacer(Modifier.height(TangemTheme.dimens3.spacing.s025)) + Spacer(Modifier.height(2.dp)) TangemNavigationText(text = text, role = TangemNavigationText.Role.Subtitle) } } diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt index dc689a98df..d95e93902a 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt @@ -30,7 +30,6 @@ import com.tangem.core.ui.haptic.HapticManager import com.tangem.core.ui.haptic.VibratorHapticManager import com.tangem.core.ui.message.EventMessageHandler import com.tangem.core.ui.res.generated.TangemColors3 -import com.tangem.core.ui.res.generated.TangemDimens3 import com.tangem.core.ui.res.generated.TangemTypography3 import com.tangem.core.ui.res.generated.lightColors3 import com.tangem.core.ui.windowsize.WindowSize @@ -201,11 +200,6 @@ object TangemTheme { @ReadOnlyComposable get() = LocalTangemDimens2.current - val dimens3: TangemDimens3 - @Composable - @ReadOnlyComposable - get() = LocalTangemDimens3.current - val shapes: TangemShapes @Composable @ReadOnlyComposable @@ -406,10 +400,6 @@ private val LocalTangemDimens2 = staticCompositionLocalOf { TangemDimens2() } -internal val LocalTangemDimens3 = staticCompositionLocalOf { - TangemDimens3() -} - internal val LocalTangemTypography3 = staticCompositionLocalOf { TangemTypography3(InterFamily) } diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt index a83c29e34b..e14447778b 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.text.selection.TextSelectionColors import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.* import com.tangem.core.ui.components.haze.ProvideHaze -import com.tangem.core.ui.res.generated.TangemDimens3 import com.tangem.core.ui.res.generated.TangemTypography3 import com.tangem.core.ui.res.generated.darkColors3 import com.tangem.core.ui.res.generated.lightColors3 @@ -29,7 +28,6 @@ fun TangemThemeRedesign(content: @Composable () -> Unit) { val rootBackgroundColor = rememberedColors.background.secondary - val tangemDimens3 = remember { TangemDimens3() } val tangemTypography3 = remember { TangemTypography3(InterFamily) } val tangemTypography2 = remember { TangemTypography2(InterFamily) } val tangemTypography = remember { TangemTypography(InterFamily, useMediumForRegular = true) } @@ -42,7 +40,6 @@ fun TangemThemeRedesign(content: @Composable () -> Unit) { LocalTangemColors provides rememberedColors, LocalTangemColors2 provides if (LocalIsInDarkTheme.current) darkThemeColors2() else lightThemeColors2(), LocalTangemColors3 provides rememberedColors3, - LocalTangemDimens3 provides tangemDimens3, LocalTangemTypography3 provides tangemTypography3, LocalTangemTypography2 provides tangemTypography2, LocalTangemTypography provides tangemTypography, diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemDimens3.kt b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemDimens3.kt deleted file mode 100644 index 6effa35ec7..0000000000 --- a/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemDimens3.kt +++ /dev/null @@ -1,110 +0,0 @@ -@file:Suppress("all") - -package com.tangem.core.ui.res.generated - -import androidx.compose.runtime.Stable -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp - -/** - * Auto-generated from design tokens. Do not edit manually. - */ -@Stable -class TangemDimens3 internal constructor( - val opacity: Opacity = Opacity(), - val blur: Blur = Blur(), - val borderRadius: BorderRadius = BorderRadius(), - val borderWidth: BorderWidth = BorderWidth(), - val size: Size = Size(), - val spacing: Spacing = Spacing(), -) { - @Stable - class Opacity internal constructor( - val disabled: Float = 0.4f, - ) - - @Stable - class Blur internal constructor( - val card: Dp = 48.dp, - val Button: Dp = 32.dp, - val Fade: Dp = 8.dp, - val None: Dp = 0.dp, - ) - - @Stable - class BorderRadius internal constructor( - val b100: Dp = 8.dp, - val b150: Dp = 12.dp, - val b200: Dp = 16.dp, - val b250: Dp = 20.dp, - val b300: Dp = 24.dp, - val b400: Dp = 32.dp, - val none: Dp = 0.dp, - val b075: Dp = 6.dp, - val b050: Dp = 4.dp, - val full: Dp = 999.dp, - ) - - @Stable - class BorderWidth internal constructor( - val none: Dp = 0.dp, - val xs: Dp = 0.5.dp, - val sm: Dp = 1.dp, - val md: Dp = 2.dp, - val lg: Dp = 4.dp, - ) - - @Stable - class Size internal constructor( - val s100: Dp = 8.dp, - val s125: Dp = 10.dp, - val s150: Dp = 12.dp, - val s200: Dp = 16.dp, - val s250: Dp = 20.dp, - val s300: Dp = 24.dp, - val s350: Dp = 28.dp, - val s400: Dp = 32.dp, - val s450: Dp = 36.dp, - val s500: Dp = 40.dp, - val s550: Dp = 44.dp, - val s600: Dp = 48.dp, - val s700: Dp = 56.dp, - val s800: Dp = 64.dp, - val s900: Dp = 72.dp, - val s1000: Dp = 80.dp, - val s1100: Dp = 88.dp, - val s1200: Dp = 96.dp, - val s025: Dp = 2.dp, - val s050: Dp = 4.dp, - val card: Card = Card(), - ) { - @Stable - class Card internal constructor( - val sm: Dp = 128.dp, - ) - } - - @Stable - class Spacing internal constructor( - val s100: Dp = 8.dp, - val s125: Dp = 10.dp, - val s150: Dp = 12.dp, - val s200: Dp = 16.dp, - val s250: Dp = 20.dp, - val s300: Dp = 24.dp, - val s350: Dp = 28.dp, - val s400: Dp = 32.dp, - val s450: Dp = 36.dp, - val s500: Dp = 40.dp, - val s550: Dp = 44.dp, - val s600: Dp = 48.dp, - val s700: Dp = 56.dp, - val s800: Dp = 64.dp, - val s900: Dp = 72.dp, - val s1000: Dp = 80.dp, - val s025: Dp = 2.dp, - val s050: Dp = 4.dp, - val s075: Dp = 6.dp, - val none: Dp = 0.dp, - ) -} \ No newline at end of file diff --git a/core/ui/token-gen/README.md b/core/ui/token-gen/README.md index 62736c8beb..c34e73747e 100644 --- a/core/ui/token-gen/README.md +++ b/core/ui/token-gen/README.md @@ -4,7 +4,18 @@ Generates Kotlin (Jetpack Compose) source files from design tokens defined in th ## Updating tokens -1. Update the `ds-tokens` submodule to the latest commit: +> **Note:** You only need `git submodule update --remote` when you want to pull **new** design tokens +> from the remote `ds-tokens` repository. If you're just regenerating Kotlin from the tokens already +> checked out (e.g. changing the generation script), **skip step 1** — don't run it without the need, +> as it moves the submodule pointer to the latest remote commit and pulls in unrelated token changes. +> +> For all other cases (a fresh checkout, or making sure the submodule is at the pinned commit), use: +> ```bash +> git submodule update --init --recursive +> ``` +> This checks out the submodule at the commit already recorded in the repo, without pulling anything new. + +1. *(Only if you need newer tokens)* Update the `ds-tokens` submodule to the latest commit: ```bash git submodule update --remote core/ui/ds-tokens ``` @@ -12,7 +23,7 @@ Generates Kotlin (Jetpack Compose) source files from design tokens defined in th ```bash cd core/ui/token-gen && npm run build ``` -3. Commit both the submodule pointer and generated files. +3. Commit the generated files (and the submodule pointer too, only if you ran step 1). ## How it works diff --git a/core/ui/token-gen/build-tokens.mjs b/core/ui/token-gen/build-tokens.mjs index ad2ced4a4e..5c185d8388 100644 --- a/core/ui/token-gen/build-tokens.mjs +++ b/core/ui/token-gen/build-tokens.mjs @@ -202,46 +202,6 @@ function renderTree(node, indent = 1) { return lines; } -/** - * Render a @Stable class tree for dimension tokens. - * Each node with children becomes a nested @Stable class. - * Props carry { default, type } values. - */ -function renderStableDimenClass(className, node, indent) { - const pad = ' '.repeat(indent); - const pad1 = ' '.repeat(indent + 1); - const lines = []; - - lines.push(`${pad}@Stable`); - lines.push(`${pad}class ${className} internal constructor(`); - - for (const { name, value } of node.props) { - lines.push(`${pad1}val ${kotlinSafe(name)}: ${value.type} = ${value.default},`); - } - for (const [childName, childNode] of node.children) { - const typeName = capitalize(childName); - const propName = kotlinSafe(childName.charAt(0).toLowerCase() + childName.slice(1)); - lines.push(`${pad1}val ${propName}: ${typeName} = ${typeName}(),`); - } - - if (node.children.size === 0) { - lines.push(`${pad})`); - } else { - lines.push(`${pad}) {`); - - let first = true; - for (const [childName, childNode] of node.children) { - if (!first) lines.push(''); - first = false; - lines.push(...renderStableDimenClass(capitalize(childName), childNode, indent + 1)); - } - - lines.push(`${pad}}`); - } - - return lines; -} - /** * Capitalize the first letter of a string. */ @@ -518,61 +478,6 @@ StyleDictionary.registerFormat({ }, }); -/** - * Kotlin format for TangemDimens3 — structured dimension tokens as @Immutable data class. - * Generates nested @Immutable data classes from codeSyntax.Android paths (prefix: TangemTheme.dimens3.). - * Includes spacing, size, borderRadius, borderWidth, blur, and semantic opacity tokens. - */ -StyleDictionary.registerFormat({ - name: 'kotlin/compose-dimens3', - format: ({ dictionary }) => { - const prefix = 'TangemTheme.dimens3.'; - - const entries = []; - for (const token of dictionary.allTokens) { - const ext = token.$extensions?.['com.figma.codeSyntax']; - if (!ext?.Android?.startsWith(prefix)) continue; - - const codePath = ext.Android.slice(prefix.length); - const segPath = codePath.split('.'); - - const raw = parseFloat(token.$value); - const tp = token.path.join('.'); - if (isNaN(raw)) throw new Error(`Non-numeric value for ${tp}: "${token.$value}"`); - - // Opacity tokens → Float, all others → Dp - const isOpacity = token.$type === 'opacity'; - const value = isOpacity ? `${raw}f` : `${raw}.dp`; - const type = isOpacity ? 'Float' : 'Dp'; - - entries.push({ path: segPath, value, type }); - } - - const tree = buildPropertyTree(entries.map(e => ({ - path: e.path, - value: { default: e.value, type: e.type }, - }))); - - const classLines = renderStableDimenClass('TangemDimens3', tree, 0); - - return [ - FILE_SUPPRESS, - '', - `package ${PACKAGE}`, - '', - 'import androidx.compose.runtime.Stable', - 'import androidx.compose.ui.unit.Dp', - 'import androidx.compose.ui.unit.dp', - '', - '/**', - ' * Auto-generated from design tokens. Do not edit manually.', - ' */', - ...classLines, - '', - ].join('\n'); - }, -}); - /** * Kotlin format for TangemTypography3 — @Stable class with nested categories. * Generates a class taking FontFamily, with nested classes for each typography category @@ -849,8 +754,8 @@ const paletteSd = new StyleDictionary({ await paletteSd.buildAllPlatforms(); console.log(' ✓ TangemColorPalette.kt'); -// Build theme-independent tokens (dimensions, typography) -console.log('\nBuilding dimension and typography tokens...'); +// Build theme-independent tokens (typography) +console.log('\nBuilding typography tokens...'); const sd = new StyleDictionary({ source: sharedBuildSets.map(s => path.join(tokensDir, `${s}.json`)), @@ -862,10 +767,6 @@ const sd = new StyleDictionary({ transforms: composePlatformTransforms, buildPath: outputDir + '/', files: [ - { - destination: 'TangemDimens3.kt', - format: 'kotlin/compose-dimens3', - }, { destination: 'TangemTypography3.kt', format: 'kotlin/compose-typography3', @@ -877,7 +778,6 @@ const sd = new StyleDictionary({ }); await sd.buildAllPlatforms(); -console.log(' ✓ TangemDimens3.kt'); console.log(' ✓ TangemTypography3.kt'); // ── Write source hash ───────────────────────────────────────────────────────── diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUiV2.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUiV2.kt index 3629c40907..814c0fc4cd 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUiV2.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUiV2.kt @@ -19,6 +19,7 @@ import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider +import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.SpacerW import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig @@ -194,7 +195,7 @@ internal fun TransactionLabel(label: TransactionLabelUM, modifier: Modifier = Mo modifier = modifier .background( color = backgroundColor, - shape = RoundedCornerShape(TangemTheme.dimens3.borderRadius.b250), + shape = RoundedCornerShape(20.dp), ) .padding( vertical = TangemTheme.dimens2.x3, diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/TangemPayCardView.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/TangemPayCardView.kt index abb75e248c..b739c67e6b 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/TangemPayCardView.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/components/TangemPayCardView.kt @@ -100,7 +100,7 @@ internal fun TangemPayAddCardView(onClick: () -> Unit, modifier: Modifier = Modi height = TangemTheme.dimens2.x10, width = TangemTheme.dimens2.x14, ) - .clip(RoundedCornerShape(TangemTheme.dimens3.borderRadius.b075)) + .clip(RoundedCornerShape(6.dp)) .background(TangemTheme.colors3.bg.opaque.primary) .clickableSingle(onClick = onClick), contentAlignment = Alignment.Center, @@ -132,7 +132,7 @@ private fun CardBackground( Box( modifier = modifier - .clip(RoundedCornerShape(TangemTheme.dimens3.borderRadius.b075)) + .clip(RoundedCornerShape(6.dp)) .drawBehind { drawRect(bgColor) @@ -159,7 +159,7 @@ private fun CardBackground( .border( width = 1.dp, color = TangemTheme.colors3.border.primary, - shape = RoundedCornerShape(TangemTheme.dimens3.borderRadius.b075), + shape = RoundedCornerShape(6.dp), ) .clickableSingle(onClick = onClick), content = content, diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/storybook/page/ds/shimmer/TangemShimmerStory.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/storybook/page/ds/shimmer/TangemShimmerStory.kt index dd6c6aba97..fa4e84e5a5 100644 --- a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/storybook/page/ds/shimmer/TangemShimmerStory.kt +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/storybook/page/ds/shimmer/TangemShimmerStory.kt @@ -80,7 +80,7 @@ private fun ComponentPreview(state: TangemShimmerStory) { modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp) - .clip(RoundedCornerShape(TangemTheme.dimens3.borderRadius.b200)) + .clip(RoundedCornerShape(16.dp)) .background(TangemTheme.colors3.bg.secondary) .padding(vertical = 24.dp, horizontal = 16.dp), ) { @@ -145,7 +145,7 @@ private fun ChipSection(label: String, content: @Composable () -> Unit) { @Composable private fun ChipGrid(items: List, label: (T) -> String, isSelected: (T) -> Boolean, onSelect: (T) -> Unit) { - val shape = RoundedCornerShape(TangemTheme.dimens3.borderRadius.full) + val shape = RoundedCornerShape(999.dp) Row( modifier = Modifier .fillMaxWidth() @@ -153,7 +153,7 @@ private fun ChipGrid(items: List, label: (T) -> String, isSelected: (T) - .clip(shape) .background(TangemTheme.colors3.bg.opaque.primary) .border( - width = TangemTheme.dimens3.borderWidth.sm, + width = 1.dp, color = TangemTheme.colors3.border.primary, shape = shape, ) @@ -173,7 +173,7 @@ private fun ChipGrid(items: List, label: (T) -> String, isSelected: (T) - @Composable private fun Chip(label: String, selected: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier) { - val chipShape = RoundedCornerShape(TangemTheme.dimens3.borderRadius.full) + val chipShape = RoundedCornerShape(999.dp) Box( contentAlignment = Alignment.Center, modifier = modifier