Updated on 2026-08-14
This commit is contained in:
parent
3fe7585ba8
commit
d0bc6087fe
34 changed files with 569 additions and 461 deletions
|
|
@ -25,13 +25,17 @@ import dev.chrisbanes.haze.HazeTint
|
|||
* elements and floating button at the bottom of the screen.
|
||||
*/
|
||||
@Composable
|
||||
fun BottomFade(modifier: Modifier = Modifier, backgroundColor: Color = TangemTheme.colors.background.secondary) {
|
||||
fun BottomFade(
|
||||
modifier: Modifier = Modifier,
|
||||
backgroundColor: Color = TangemTheme.colors.background.secondary,
|
||||
height: Dp = 100.dp,
|
||||
) {
|
||||
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.height(TangemTheme.dimens.size100 + bottomBarHeight)
|
||||
.height(height + bottomBarHeight)
|
||||
.background(
|
||||
brush = Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
|
|
|
|||
|
|
@ -6,12 +6,14 @@ import androidx.compose.material3.CardColors
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
@Composable
|
||||
fun BlockCard(
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
shape: Shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
colors: CardColors = TangemBlockCardColors,
|
||||
onClick: () -> Unit = {},
|
||||
content: @Composable ColumnScope.() -> Unit = {},
|
||||
|
|
@ -19,7 +21,7 @@ fun BlockCard(
|
|||
Card(
|
||||
modifier = modifier,
|
||||
onClick = onClick,
|
||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
shape = shape,
|
||||
colors = colors,
|
||||
enabled = enabled,
|
||||
content = content,
|
||||
|
|
|
|||
|
|
@ -127,13 +127,13 @@ private fun DescriptionItemV2(
|
|||
onClick = onReadMoreClick,
|
||||
),
|
||||
text = text,
|
||||
style = TangemTheme.typography2.bodyRegular15,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
modifier = modifier,
|
||||
text = description.resolveReference(),
|
||||
style = TangemTheme.typography2.bodyRegular15,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
)
|
||||
}
|
||||
|
|
@ -179,17 +179,17 @@ private fun DescriptionPlaceholderV2(modifier: Modifier = Modifier) {
|
|||
) {
|
||||
TextShimmer(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
style = TangemTheme.typography2.bodyRegular15,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
TextShimmer(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
style = TangemTheme.typography2.bodyRegular15,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
TextShimmer(
|
||||
modifier = Modifier.fillMaxWidth(fraction = 0.8f),
|
||||
style = TangemTheme.typography2.bodyRegular15,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,20 +14,20 @@ 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.graphics.Color
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.*
|
||||
import com.tangem.core.ui.components.haze.hazeEffectTangem
|
||||
import com.tangem.core.ui.extensions.conditionalCompose
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import dev.chrisbanes.haze.HazeState
|
||||
import dev.chrisbanes.haze.rememberHazeState
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -63,6 +63,7 @@ private val SMALL_DOT_SIZE = DpSize(4.dp, 4.dp)
|
|||
fun TangemPagerIndicator(
|
||||
pagerState: PagerState,
|
||||
modifier: Modifier = Modifier,
|
||||
hazeState: HazeState = rememberHazeState(),
|
||||
colors: PagerIndicatorColors = TangemPagerIndicatorColors,
|
||||
) {
|
||||
val totalPages = pagerState.pageCount
|
||||
|
|
@ -84,10 +85,12 @@ fun TangemPagerIndicator(
|
|||
.width(getSize(totalPages))
|
||||
.conditionalCompose(colors.overlay != null) {
|
||||
colors.overlay?.let { overlay ->
|
||||
background(
|
||||
color = overlay,
|
||||
shape = CircleShape,
|
||||
)
|
||||
this
|
||||
.clip(CircleShape)
|
||||
.hazeEffectTangem(hazeState) {
|
||||
this.blurRadius = 16.dp
|
||||
backgroundColor = overlay
|
||||
}
|
||||
} ?: this
|
||||
}
|
||||
.padding(TangemTheme.dimens2.x3),
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package com.tangem.core.ui.ds.tabs
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.core.AnimationSpec
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.snap
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
|
|
@ -86,7 +88,7 @@ fun TangemSegmentedPicker(
|
|||
val density = LocalDensity.current
|
||||
|
||||
val itemsWidths = remember { mutableStateListOf(*Array(items.size) { 0.dp }) }
|
||||
val selectedIndex = remember { mutableStateOf(items.indexOfFirstOrNull { it == initialSelectedItem } ?: 0) }
|
||||
val selectedIndex = remember { mutableIntStateOf(items.indexOfFirstOrNull { it == initialSelectedItem } ?: 0) }
|
||||
val segmentHeight = remember { mutableStateOf(0.dp) }
|
||||
|
||||
val shape = RoundedCornerShape(TangemTheme.dimens2.x25)
|
||||
|
|
@ -105,7 +107,7 @@ fun TangemSegmentedPicker(
|
|||
) {
|
||||
SegmentSelection(
|
||||
itemsWidths = itemsWidths,
|
||||
selectedIndex = selectedIndex.value,
|
||||
selectedIndex = selectedIndex.intValue,
|
||||
segmentHeight = segmentHeight.value,
|
||||
)
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
|
|
@ -151,18 +153,30 @@ fun TangemSegmentedPicker(
|
|||
|
||||
@Composable
|
||||
private fun SegmentSelection(itemsWidths: SnapshotStateList<Dp>, selectedIndex: Int, segmentHeight: Dp) {
|
||||
var hasInitiallyMeasured by remember { mutableStateOf(false) }
|
||||
|
||||
val animationSpec: AnimationSpec<Dp> = if (hasInitiallyMeasured) {
|
||||
tween(durationMillis = 300)
|
||||
} else {
|
||||
snap()
|
||||
}
|
||||
|
||||
val indicatorOffset by animateDpAsState(
|
||||
targetValue = itemsWidths.take(selectedIndex).fold(0.dp, Dp::plus),
|
||||
animationSpec = tween(durationMillis = 300),
|
||||
animationSpec = animationSpec,
|
||||
label = "indicatorOffset",
|
||||
)
|
||||
|
||||
val indicatorWidth by animateDpAsState(
|
||||
targetValue = itemsWidths[selectedIndex],
|
||||
animationSpec = tween(durationMillis = 300),
|
||||
animationSpec = animationSpec,
|
||||
label = "indicatorWidth",
|
||||
)
|
||||
|
||||
LaunchedEffect(itemsWidths[selectedIndex] > 0.dp) {
|
||||
if (itemsWidths[selectedIndex] > 0.dp) hasInitiallyMeasured = true
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.offset {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue