Updated on 2026-08-14
This commit is contained in:
commit
00ddaf9b12
4 changed files with 114 additions and 15 deletions
|
|
@ -0,0 +1,89 @@
|
|||
package com.tangem.core.ui.components
|
||||
|
||||
import androidx.compose.animation.core.AnimationSpec
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.systemBars
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.composed
|
||||
import androidx.compose.ui.draw.drawWithContent
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
@Composable
|
||||
fun Modifier.edgeFade(
|
||||
vararg positions: FadePosition,
|
||||
size: Dp,
|
||||
isVisible: Boolean = true,
|
||||
animationSpec: AnimationSpec<Dp>? = null,
|
||||
color: Color = TangemTheme.colors.background.secondary,
|
||||
): Modifier = composed {
|
||||
require(value = size > 0.dp) {
|
||||
"Size must be greater than '0'"
|
||||
}
|
||||
val animatedSize = animationSpec?.let {
|
||||
animateDpAsState(
|
||||
targetValue = if (isVisible) size else 0.dp,
|
||||
animationSpec = it,
|
||||
label = "Edge fade width",
|
||||
)
|
||||
}
|
||||
|
||||
drawWithContent {
|
||||
drawContent()
|
||||
|
||||
positions.forEach { side ->
|
||||
val (start, end) = this.size.getFadeOffsets(side)
|
||||
|
||||
val staticSizePx = if (isVisible) size.toPx() else 0f
|
||||
val sizePx = animatedSize?.value?.toPx() ?: staticSizePx
|
||||
|
||||
val fraction = when (side) {
|
||||
FadePosition.LEFT, FadePosition.RIGHT -> sizePx / this.size.width
|
||||
FadePosition.BOTTOM, FadePosition.TOP -> sizePx / this.size.height
|
||||
}
|
||||
|
||||
drawRect(
|
||||
brush = Brush.linearGradient(
|
||||
0f to color,
|
||||
fraction to Color.Transparent,
|
||||
start = start,
|
||||
end = end,
|
||||
),
|
||||
size = this.size,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Modifier.bottomFade(
|
||||
height: Dp = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() } + 96.dp,
|
||||
color: Color = TangemTheme.colors.background.secondary,
|
||||
): Modifier = edgeFade(
|
||||
FadePosition.BOTTOM,
|
||||
size = height,
|
||||
color = color,
|
||||
)
|
||||
|
||||
enum class FadePosition {
|
||||
TOP, BOTTOM, LEFT, RIGHT;
|
||||
}
|
||||
|
||||
@Stable
|
||||
private fun Size.getFadeOffsets(position: FadePosition): Pair<Offset, Offset> {
|
||||
return when (position) {
|
||||
FadePosition.LEFT -> Offset.Zero to Offset(width, 0f)
|
||||
FadePosition.RIGHT -> Offset(width, y = 0f) to Offset.Zero
|
||||
FadePosition.BOTTOM -> Offset(x = 0f, height) to Offset.Zero
|
||||
FadePosition.TOP -> Offset.Zero to Offset(x = 0f, height)
|
||||
}
|
||||
}
|
||||
|
|
@ -55,8 +55,8 @@ internal class PreviewCustomTokenSelectorComponent(
|
|||
network = Network(
|
||||
id = n.id,
|
||||
backendId = n.id.value,
|
||||
name = "",
|
||||
currencySymbol = "",
|
||||
name = "Network $index",
|
||||
currencySymbol = "N$index",
|
||||
derivationPath = Network.DerivationPath.Card(""),
|
||||
isTestnet = false,
|
||||
standardType = Network.StandardType.ERC20,
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@ import androidx.compose.ui.res.stringResource
|
|||
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.dp
|
||||
import androidx.compose.ui.util.fastForEach
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.block.information.InformationBlock
|
||||
import com.tangem.core.ui.components.bottomFade
|
||||
import com.tangem.core.ui.components.fields.SimpleTextField
|
||||
import com.tangem.core.ui.components.isOpened
|
||||
import com.tangem.core.ui.components.keyboardAsState
|
||||
|
|
@ -60,18 +62,24 @@ internal fun CustomTokenFormContent(model: CustomTokenFormUM, modifier: Modifier
|
|||
.fillMaxSize()
|
||||
.background(color = TangemTheme.colors.background.secondary),
|
||||
) {
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
Column(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.verticalScroll(scrollState)
|
||||
.fillMaxSize()
|
||||
.padding(bottom = TangemTheme.dimens.spacing76),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
|
||||
.bottomFade(),
|
||||
) {
|
||||
AddCustomTokenDescription()
|
||||
FormContent(model)
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(scrollState)
|
||||
.fillMaxSize()
|
||||
.padding(bottom = 128.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
AddCustomTokenDescription()
|
||||
FormContent(model)
|
||||
}
|
||||
}
|
||||
|
||||
PrimaryButton(
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ import androidx.compose.ui.res.stringResource
|
|||
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.dp
|
||||
import com.tangem.core.ui.components.block.information.InformationBlock
|
||||
import com.tangem.core.ui.components.bottomFade
|
||||
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
||||
import com.tangem.core.ui.components.rows.ChainRow
|
||||
import com.tangem.core.ui.components.rows.model.ChainRowUM
|
||||
|
|
@ -46,11 +48,11 @@ internal fun CustomTokenSelectorContent(model: CustomTokenSelectorUM, modifier:
|
|||
val lastIndex = model.items.lastIndex
|
||||
|
||||
LazyColumn(
|
||||
modifier = modifier.background(
|
||||
color = TangemTheme.colors.background.secondary,
|
||||
),
|
||||
modifier = modifier
|
||||
.background(color = TangemTheme.colors.background.secondary)
|
||||
.bottomFade(),
|
||||
contentPadding = PaddingValues(
|
||||
bottom = TangemTheme.dimens.spacing16 + bottomBarHeight,
|
||||
bottom = 96.dp + bottomBarHeight,
|
||||
),
|
||||
) {
|
||||
item {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue