diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds2/shimmers/TangemShimmer.kt b/core/ui/src/main/java/com/tangem/core/ui/ds2/shimmers/TangemShimmer.kt index ce0f10ab05..93725819d4 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/ds2/shimmers/TangemShimmer.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/ds2/shimmers/TangemShimmer.kt @@ -6,6 +6,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.* +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.drawWithCache @@ -14,7 +15,7 @@ import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.rememberTextMeasurer +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 @@ -24,25 +25,17 @@ import kotlin.math.cos import kotlin.math.sin /** - * Design-system rectangle shimmer placeholder. + * Design-system v2 shimmer placeholder — a rounded rectangle with a sweeping highlight. * - * A rounded rectangle painted with `bg.opaque.secondary`. A tilted band sweeps across it where - * the base color's alpha is gradually dimmed toward the center of the band and restored at the - * edges, producing a soft "blade" highlight passing through the placeholder. The alpha profile - * matches [com.tangem.core.ui.components.text.BladeAnimation]. - * - * Cycle: 1.5s hold → 0.8s linear sweep → restart. - * - * Version 1.0 * [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=3398-625&p=f&m=dev) * - * Sizing is the caller's responsibility — set width and height via [modifier]. + * For a placeholder sized after a typography line, use the [TangemShimmer] text overload instead. * - * @param modifier Modifier applied to the shimmer's root. + * @param modifier Modifier applied to the shimmer's root. Set the width and height here. * @param radius Corner radius of the rectangle. */ @Composable -fun RectangleShimmer(modifier: Modifier = Modifier, radius: Dp = 6.dp) { +fun TangemShimmer(modifier: Modifier = Modifier, radius: Dp = TangemShimmer.DefaultRadius) { val baseColor = TangemTheme.colors3.bg.opaque.secondary val progress = LocalTangemShimmerProgress.current ?: rememberShimmerProgressInstance() val colorStops = remember(baseColor) { buildColorStops(baseColor) } @@ -77,63 +70,76 @@ fun RectangleShimmer(modifier: Modifier = Modifier, radius: Dp = 6.dp) { } /** - * Text-sized shimmer placeholder. Sizes itself to the bounding box of the [text] measured in the - * typography preset selected by [style], plus the preset's vertical padding (top + bottom). + * Text-line shimmer placeholder, sized and styled after the typography line described by [style]. * - * @param text Text used to determine the shimmer's size. Not drawn. - * @param style Typography preset — drives both the measurement style and the vertical padding. - * @param radius Corner radius of the rectangle. + * [Figma](https://www.figma.com/design/AsnJ5CPHib4Qxw12gszjMS/%F0%9F%92%A0-DS-Components?node-id=3398-625&p=f&m=dev) + * + * @param style A [TangemTheme.typography3] style (e.g. `TangemTheme.typography3.body.medium`) the + * placeholder is sized after. Unrecognized styles fall back to `body.medium`. * @param modifier Modifier applied to the shimmer's root. + * @param textAlign Horizontal position of the block within the parent width. */ @Composable -fun TextShimmer(text: String, style: TextShimmerStyle, radius: Dp, modifier: Modifier = Modifier) { - val textStyle = style.toTextStyle() - val measurer = rememberTextMeasurer() - val density = LocalDensity.current - val (widthDp, heightDp) = remember(text, textStyle, measurer, density) { - val measured = measurer.measure(text = text, style = textStyle) - with(density) { measured.size.width.toDp() to measured.size.height.toDp() } +fun TangemShimmer(style: TextStyle, modifier: Modifier = Modifier, textAlign: TextAlign = TextAlign.Start) { + val preset = TangemShimmer.TextPreset.forStyle(style) + val lineHeightDp = with(LocalDensity.current) { style.lineHeight.toDp() } + val alignment = when (textAlign) { + TextAlign.Center -> Alignment.Center + TextAlign.End -> Alignment.CenterEnd + else -> Alignment.CenterStart } - RectangleShimmer( - modifier = modifier.size( - width = widthDp, - height = heightDp + style.verticalPadding * 2, - ), - radius = radius, - ) + Box( + modifier = modifier.fillMaxWidth(), + contentAlignment = alignment, + ) { + TangemShimmer( + modifier = Modifier + .fillMaxWidth(preset.widthFraction) + .height(lineHeightDp) + .padding(vertical = preset.verticalPadding), + radius = preset.radius, + ) + } +} + +/** Public API namespace for [TangemShimmer]. */ +object TangemShimmer { + + /** Default corner radius of the rectangle shimmer. */ + val DefaultRadius: Dp = 6.dp + + /** Per-typography sizing for the [TangemShimmer] text overload. */ + internal enum class TextPreset(val widthFraction: Float, val verticalPadding: Dp, val radius: Dp) { + Display(widthFraction = 0.5f, verticalPadding = 4.dp, radius = 12.dp), + HeadingMedium(widthFraction = 0.7f, verticalPadding = 2.dp, radius = 8.dp), + HeadingSmall(widthFraction = 0.6f, verticalPadding = 2.dp, radius = 16.dp), + Body(widthFraction = 0.5f, verticalPadding = 2.dp, radius = 16.dp), + Subheading(widthFraction = 0.4f, verticalPadding = 2.dp, radius = 16.dp), + Caption(widthFraction = 0.3f, verticalPadding = 2.dp, radius = 16.dp), + ; + + companion object { + @Composable + @ReadOnlyComposable + fun forStyle(style: TextStyle): TextPreset { + val typography = TangemTheme.typography3 + return when (style) { + typography.display.medium -> Display + typography.heading.medium -> HeadingMedium + typography.heading.small -> HeadingSmall + typography.subheading.medium -> Subheading + typography.caption.medium -> Caption + else -> Body + } + } + } + } } /** - * Typography preset for [TextShimmer]. Each preset maps to a [TangemTheme.typography3] style - * and contributes additional [verticalPadding] applied to both top and bottom — the shimmer - * block ends up `2 * verticalPadding` taller than the raw measured text. - */ -enum class TextShimmerStyle(val verticalPadding: Dp) { - DISPLAY(verticalPadding = 4.dp), - HEADING_MEDIUM(verticalPadding = 2.dp), - HEADING_SMALL(verticalPadding = 2.dp), - BODY(verticalPadding = 2.dp), - SUBHEADING(verticalPadding = 2.dp), - CAPTION(verticalPadding = 2.dp), -} - -@Composable -@ReadOnlyComposable -private fun TextShimmerStyle.toTextStyle(): TextStyle = when (this) { - TextShimmerStyle.DISPLAY -> TangemTheme.typography3.display.medium - TextShimmerStyle.HEADING_MEDIUM -> TangemTheme.typography3.heading.medium - TextShimmerStyle.HEADING_SMALL -> TangemTheme.typography3.heading.small - TextShimmerStyle.BODY -> TangemTheme.typography3.body.medium - TextShimmerStyle.SUBHEADING -> TangemTheme.typography3.subheading.medium - TextShimmerStyle.CAPTION -> TangemTheme.typography3.caption.medium -} - -/** - * Wraps [content] so every [RectangleShimmer] / [TextShimmer] inside reuses a single shimmer - * animation driver. Without this provider each shimmer creates its own - * [rememberInfiniteTransition] — that scales poorly in lists and lets sweeps drift out of phase. - * Safe to nest; safe to omit (each shimmer falls back to its own driver). + * Wraps [content] so every [TangemShimmer] inside shares a single, in-phase animation driver — + * use it around lists of shimmers. Safe to nest; safe to omit. */ @Composable fun ProvideTangemShimmer(content: @Composable () -> Unit) { @@ -198,24 +204,16 @@ private fun TangemShimmerPreview() { .padding(16.dp), verticalArrangement = Arrangement.spacedBy(12.dp), ) { - RectangleShimmer( + TangemShimmer( modifier = Modifier.size(width = 200.dp, height = 24.dp), radius = 6.dp, ) - RectangleShimmer( + TangemShimmer( modifier = Modifier.size(width = 120.dp, height = 16.dp), radius = 4.dp, ) - TextShimmer( - text = "Account balance", - style = TextShimmerStyle.BODY, - radius = 4.dp, - ) - TextShimmer( - text = "$12,345.67", - style = TextShimmerStyle.HEADING_MEDIUM, - radius = 6.dp, - ) + TangemShimmer(style = TangemTheme.typography3.body.medium) + TangemShimmer(style = TangemTheme.typography3.heading.medium) } } } 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 8dc5a78cec..cc4967aeb3 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,6 +7,7 @@ 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.ds2.shimmers.ProvideTangemShimmer import com.tangem.core.ui.res.generated.TangemTypography3 import com.tangem.core.ui.res.generated.darkColors3 import com.tangem.core.ui.res.generated.lightColors3 @@ -48,8 +49,10 @@ fun TangemThemeRedesign(content: @Composable () -> Unit) { CompositionLocalProvider( LocalTextSelectionColors provides TangemTextSelectionColors2, ) { - ProvideHaze { - content() + ProvideTangemShimmer { + ProvideHaze { + content() + } } } } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupScreenV2.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupScreenV2.kt index 4a14ae9223..24a093cf73 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupScreenV2.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/limit/setup/TangemPayCardLimitSetupScreenV2.kt @@ -25,8 +25,7 @@ import com.tangem.core.ui.components.fields.visualtransformations.AmountVisualTr import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.ds.topbar.TangemTopBar import com.tangem.core.ui.ds2.button.TangemButton -import com.tangem.core.ui.ds2.shimmers.TextShimmer -import com.tangem.core.ui.ds2.shimmers.TextShimmerStyle +import com.tangem.core.ui.ds2.shimmers.TangemShimmer import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.res.TangemTheme @@ -105,11 +104,7 @@ private fun AmountBlock(state: TangemPayCardLimitSetupUM, modifier: Modifier = M color = TangemTheme.colors3.text.tertiary, ) if (state.isInitialDataLoading) { - TextShimmer( - style = TextShimmerStyle.HEADING_MEDIUM, - text = "$ 10000", - radius = TangemTheme.dimens2.x25, - ) + TangemShimmer(style = TangemTheme.typography3.heading.medium) } else { val colors = TangemAmountTextFieldColors.copy( textColor = TangemTheme.colors3.text.primary, diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDailyLimitBlock.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDailyLimitBlock.kt index 29433dc21d..77d497c2ff 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDailyLimitBlock.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDailyLimitBlock.kt @@ -28,9 +28,7 @@ import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.ds.row.TangemRowContainer import com.tangem.core.ui.ds.row.TangemRowLayoutId import com.tangem.core.ui.ds2.button.TangemButton -import com.tangem.core.ui.ds2.shimmers.RectangleShimmer -import com.tangem.core.ui.ds2.shimmers.TextShimmer -import com.tangem.core.ui.ds2.shimmers.TextShimmerStyle +import com.tangem.core.ui.ds2.shimmers.TangemShimmer import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.* @@ -180,7 +178,7 @@ private fun CurrentLimitBlockV2(state: TangemPayDailyLimitBlockState, modifier: ) } TangemPayDailyLimitBlockState.Loading -> { - RectangleShimmer( + TangemShimmer( modifier = Modifier .padding(start = TangemTheme.dimens2.x3) .layoutId(TangemRowLayoutId.TAIL) @@ -273,12 +271,7 @@ private fun SubtitleLimit(state: TangemPayDailyLimitBlockState, modifier: Modifi ) } TangemPayDailyLimitBlockState.Loading -> { - TextShimmer( - radius = TangemTheme.dimens2.x25, - modifier = modifier, - style = TextShimmerStyle.BODY, - text = "$50,000", - ) + TangemShimmer(modifier = modifier, style = TangemTheme.typography3.body.medium) } } } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsScreenV2.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsScreenV2.kt index faa9c8cce9..af810d7679 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsScreenV2.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayDetailsScreenV2.kt @@ -44,8 +44,7 @@ import com.tangem.core.ui.ds.message.TangemMessage import com.tangem.core.ui.ds.message.TangemMessageEffect import com.tangem.core.ui.ds.topbar.TangemTopBar import com.tangem.core.ui.ds2.button.TangemButton -import com.tangem.core.ui.ds2.shimmers.TextShimmer -import com.tangem.core.ui.ds2.shimmers.TextShimmerStyle +import com.tangem.core.ui.ds2.shimmers.TangemShimmer import com.tangem.core.ui.extensions.orMaskWithStars import com.tangem.core.ui.extensions.resolveAnnotatedReference import com.tangem.core.ui.extensions.resourceReference @@ -343,11 +342,8 @@ private fun BalanceBlock( }, ) { animatedState -> when (animatedState) { - is TangemPayDetailsBalanceBlockState.Loading -> TextShimmer( - modifier = Modifier.size(width = 160.dp, height = 56.dp), - text = "1234.00", - style = TextShimmerStyle.HEADING_MEDIUM, - radius = TangemTheme.dimens2.x25, + is TangemPayDetailsBalanceBlockState.Loading -> TangemShimmer( + style = TangemTheme.typography3.heading.medium, ) is TangemPayDetailsBalanceBlockState.Content -> Text( modifier = Modifier.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_BALANCE), diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayReissueCardContentV2.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayReissueCardContentV2.kt index bcb076ed11..e567d483d2 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayReissueCardContentV2.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayReissueCardContentV2.kt @@ -31,8 +31,7 @@ import com.tangem.core.ui.ds2.row.TangemRow import com.tangem.core.ui.ds2.row.TangemRowContentLead import com.tangem.core.ui.ds2.row.TangemRowText import com.tangem.core.ui.ds2.row.TangemRowTextRole -import com.tangem.core.ui.ds2.shimmers.TextShimmer -import com.tangem.core.ui.ds2.shimmers.TextShimmerStyle +import com.tangem.core.ui.ds2.shimmers.TangemShimmer import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme @@ -174,11 +173,7 @@ private fun FeeInfoRow(titleRes: Int, value: String, showDivider: Boolean = fals }, valueSlot = { if (value.isEmpty()) { - TextShimmer( - text = "$ 0.00", - style = TextShimmerStyle.BODY, - radius = 48.dp, - ) + TangemShimmer(style = TangemTheme.typography3.body.medium) } else { TangemRowText( text = value, diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUiV2.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUiV2.kt index ba14336023..7ed83f195e 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUiV2.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUiV2.kt @@ -29,9 +29,7 @@ import com.tangem.core.ui.ds2.row.TangemRow import com.tangem.core.ui.ds2.row.TangemRowText import com.tangem.core.ui.ds2.row.TangemRowTextRole import com.tangem.core.ui.ds2.row.TangemRowVerticalAlignment -import com.tangem.core.ui.ds2.shimmers.RectangleShimmer -import com.tangem.core.ui.ds2.shimmers.TextShimmer -import com.tangem.core.ui.ds2.shimmers.TextShimmerStyle +import com.tangem.core.ui.ds2.shimmers.TangemShimmer import com.tangem.core.ui.extensions.orMaskWithStars import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.res.TangemTheme @@ -175,12 +173,7 @@ private fun GroupTitleBlock( .fillMaxWidth() .padding(top = 6.dp, start = 16.dp), ) { - TextShimmer( - modifier = Modifier.width(TangemTheme.dimens2.x10), - text = state.title, - style = TextShimmerStyle.SUBHEADING, - radius = TangemTheme.dimens2.x25, - ) + TangemShimmer(style = TangemTheme.typography3.subheading.medium) } } else { Text( @@ -224,7 +217,7 @@ private fun Icon(state: TangemPayTransactionState, modifier: Modifier = Modifier iconState = state.iconV2, modifier = modifier, ) - is TangemPayTransactionState.Loading -> RectangleShimmer( + is TangemPayTransactionState.Loading -> TangemShimmer( modifier = modifier.size(TangemTheme.dimens2.x10), radius = TangemTheme.dimens2.x25, ) @@ -266,12 +259,7 @@ private fun Title(state: TangemPayTransactionState, modifier: Modifier = Modifie TangemRowText(text = state.title.resolveReference(), role = TangemRowTextRole.Title) } is TangemPayTransactionState.Loading -> { - TextShimmer( - modifier = modifier, - text = "Transfer", - radius = TangemTheme.dimens2.x25, - style = TextShimmerStyle.BODY, - ) + TangemShimmer(modifier = modifier, style = TangemTheme.typography3.body.medium) } } } @@ -283,12 +271,7 @@ private fun Subtitle(state: TangemPayTransactionState, modifier: Modifier = Modi TangemRowText(text = state.subtitle.resolveReference(), role = TangemRowTextRole.Subtitle) } is TangemPayTransactionState.Loading -> { - TextShimmer( - modifier = modifier, - text = "Transfer", - radius = TangemTheme.dimens2.x25, - style = TextShimmerStyle.CAPTION, - ) + TangemShimmer(modifier = modifier, style = TangemTheme.typography3.caption.medium) } } } @@ -306,12 +289,7 @@ private fun Amount(state: TangemPayTransactionState, isBalanceHidden: Boolean, m ) } is TangemPayTransactionState.Loading -> { - TextShimmer( - modifier = modifier, - text = "10000", - radius = TangemTheme.dimens2.x25, - style = TextShimmerStyle.BODY, - ) + TangemShimmer(modifier = modifier, style = TangemTheme.typography3.body.medium) } } } @@ -323,12 +301,7 @@ private fun Timestamp(state: TangemPayTransactionState, modifier: Modifier = Mod TangemRowText(text = state.time, role = TangemRowTextRole.Subvalue) } is TangemPayTransactionState.Loading -> { - TextShimmer( - modifier = modifier, - text = "00:00", - radius = TangemTheme.dimens2.x25, - style = TextShimmerStyle.CAPTION, - ) + TangemShimmer(modifier = modifier, style = TangemTheme.typography3.caption.medium) } } } diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/storybook/entity/StoryBookPage.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/storybook/entity/StoryBookPage.kt index 1d461a65c9..2e1b42692f 100644 --- a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/storybook/entity/StoryBookPage.kt +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/storybook/entity/StoryBookPage.kt @@ -12,7 +12,6 @@ import com.tangem.core.ui.ds2.fade.TangemFade import com.tangem.core.ui.ds2.loader.TangemLoaderSize import com.tangem.core.ui.ds2.row.TangemRowContentLead import com.tangem.core.ui.ds2.row.TangemRowVerticalAlignment -import com.tangem.core.ui.ds2.shimmers.TextShimmerStyle import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation internal sealed interface StoryBookPage @@ -113,16 +112,35 @@ internal data class TangemLoaderStory( @Immutable internal data class TangemShimmerStory( - val textStyle: TextShimmerStyle, + val textStyle: TextStyleOption, + val textPosition: TextPositionOption, val radius: RadiusOption, val rectangleWidth: RectangleWidthOption, val rectangleHeight: RectangleHeightOption, - val onTextStyleChange: (TextShimmerStyle) -> Unit, + val onTextStyleChange: (TextStyleOption) -> Unit, + val onTextPositionChange: (TextPositionOption) -> Unit, val onRadiusChange: (RadiusOption) -> Unit, val onRectangleWidthChange: (RectangleWidthOption) -> Unit, val onRectangleHeightChange: (RectangleHeightOption) -> Unit, ) : DsStoryBookPage { + /** Selectable typography preset for the `TangemShimmer` text variant. */ + enum class TextStyleOption { + DISPLAY, + HEADING_MEDIUM, + HEADING_SMALL, + BODY, + SUBHEADING, + CAPTION, + } + + /** Horizontal position of the `TangemShimmer` text block within the parent width. */ + enum class TextPositionOption(val label: String) { + START("Start"), + CENTER("Center"), + END("End"), + } + /** Selectable corner radius (matches `borderRadius` tokens). */ enum class RadiusOption(val label: String) { R4("4dp"), diff --git a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/storybook/page/ds/shimmer/Build.kt b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/storybook/page/ds/shimmer/Build.kt index 89745a686a..6804eb3fb2 100644 --- a/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/storybook/page/ds/shimmer/Build.kt +++ b/features/tester/impl/src/main/java/com/tangem/feature/tester/presentation/storybook/page/ds/shimmer/Build.kt @@ -1,19 +1,22 @@ package com.tangem.feature.tester.presentation.storybook.page.ds.shimmer -import com.tangem.core.ui.ds2.shimmers.TextShimmerStyle import com.tangem.feature.tester.presentation.storybook.entity.TangemShimmerStory import com.tangem.feature.tester.presentation.storybook.viewmodel.StateUpdater import com.tangem.feature.tester.presentation.storybook.viewmodel.storyPageFactory internal fun StateUpdater.build(): TangemShimmerStory { return TangemShimmerStory( - textStyle = TextShimmerStyle.BODY, + textStyle = TangemShimmerStory.TextStyleOption.BODY, + textPosition = TangemShimmerStory.TextPositionOption.START, radius = TangemShimmerStory.RadiusOption.R24, rectangleWidth = TangemShimmerStory.RectangleWidthOption.W240, rectangleHeight = TangemShimmerStory.RectangleHeightOption.H24, onTextStyleChange = { textStyle -> updateStory { it.copy(textStyle = textStyle) } }, + onTextPositionChange = { position -> + updateStory { it.copy(textPosition = position) } + }, onRadiusChange = { radius -> updateStory { it.copy(radius = radius) } }, 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 fa4e84e5a5..e526c53cb7 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 @@ -12,9 +12,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import com.tangem.core.ui.ds2.shimmers.RectangleShimmer -import com.tangem.core.ui.ds2.shimmers.TextShimmer -import com.tangem.core.ui.ds2.shimmers.TextShimmerStyle +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextAlign +import com.tangem.core.ui.ds2.shimmers.TangemShimmer import com.tangem.core.ui.res.TangemTheme import com.tangem.feature.tester.presentation.storybook.entity.TangemShimmerStory import com.tangem.feature.tester.presentation.storybook.entity.TangemShimmerStory.* @@ -38,12 +38,20 @@ internal fun TangemShimmerStory(state: TangemShimmerStory, modifier: Modifier = ) { ChipSection(label = "Text style") { ChipGrid( - items = TextShimmerStyle.entries, + items = TextStyleOption.entries, label = { it.chipLabel() }, isSelected = { it == state.textStyle }, onSelect = state.onTextStyleChange, ) } + ChipSection(label = "Text position") { + ChipGrid( + items = TextPositionOption.entries, + label = { it.label }, + isSelected = { it == state.textPosition }, + onSelect = state.onTextPositionChange, + ) + } ChipSection(label = "Radius") { ChipGrid( items = RadiusOption.entries, @@ -89,18 +97,17 @@ private fun ComponentPreview(state: TangemShimmerStory) { horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth(), ) { - PreviewLabel(text = "RectangleShimmer") + PreviewLabel(text = "TangemShimmer · rectangle") RectangleShimmerPreview( width = state.rectangleWidth, height = state.rectangleHeight, radius = radius, ) - PreviewLabel(text = "TextShimmer · ${state.textStyle.chipLabel()}") - TextShimmer( - text = SAMPLE_TEXT, - style = state.textStyle, - radius = radius, + PreviewLabel(text = "TangemShimmer · text · ${state.textStyle.chipLabel()}") + TangemShimmer( + style = state.textStyle.toTextStyle(), + textAlign = state.textPosition.toTextAlign(), ) } } @@ -113,7 +120,7 @@ private fun RectangleShimmerPreview(width: RectangleWidthOption, height: Rectang else -> Modifier.width(width.value()) }.height(height.value()) - RectangleShimmer( + TangemShimmer( modifier = sizeModifier, radius = radius, ) @@ -194,13 +201,29 @@ private fun Chip(label: String, selected: Boolean, onClick: () -> Unit, modifier // endregion -private fun TextShimmerStyle.chipLabel(): String = when (this) { - TextShimmerStyle.DISPLAY -> "Display" - TextShimmerStyle.HEADING_MEDIUM -> "Head.M" - TextShimmerStyle.HEADING_SMALL -> "Head.S" - TextShimmerStyle.BODY -> "Body" - TextShimmerStyle.SUBHEADING -> "Sub.H" - TextShimmerStyle.CAPTION -> "Caption" +private fun TextStyleOption.chipLabel(): String = when (this) { + TextStyleOption.DISPLAY -> "Display" + TextStyleOption.HEADING_MEDIUM -> "Head.M" + TextStyleOption.HEADING_SMALL -> "Head.S" + TextStyleOption.BODY -> "Body" + TextStyleOption.SUBHEADING -> "Sub.H" + TextStyleOption.CAPTION -> "Caption" +} + +@Composable +private fun TextStyleOption.toTextStyle(): TextStyle = when (this) { + TextStyleOption.DISPLAY -> TangemTheme.typography3.display.medium + TextStyleOption.HEADING_MEDIUM -> TangemTheme.typography3.heading.medium + TextStyleOption.HEADING_SMALL -> TangemTheme.typography3.heading.small + TextStyleOption.BODY -> TangemTheme.typography3.body.medium + TextStyleOption.SUBHEADING -> TangemTheme.typography3.subheading.medium + TextStyleOption.CAPTION -> TangemTheme.typography3.caption.medium +} + +private fun TextPositionOption.toTextAlign(): TextAlign = when (this) { + TextPositionOption.START -> TextAlign.Start + TextPositionOption.CENTER -> TextAlign.Center + TextPositionOption.END -> TextAlign.End } private fun RadiusOption.value(): Dp = when (this) { @@ -224,6 +247,4 @@ private fun RectangleHeightOption.value(): Dp = when (this) { RectangleHeightOption.H24 -> 24.dp RectangleHeightOption.H40 -> 40.dp RectangleHeightOption.H64 -> 64.dp -} - -private const val SAMPLE_TEXT = "Sample shimmer text" \ No newline at end of file +} \ No newline at end of file