Updated on 2026-08-14

This commit is contained in:
Tangem 2024-03-21 12:25:43 +05:00
parent b28720df71
commit 4d74432402
18 changed files with 680 additions and 393 deletions

View file

@ -18,6 +18,7 @@ fun AppBarWithBackButtonAndIcon(
onBackClick: () -> Unit,
modifier: Modifier = Modifier,
text: String? = null,
subtitle: String? = null,
@DrawableRes backIconRes: Int? = null,
@DrawableRes iconRes: Int? = null,
onIconClick: (() -> Unit)? = null,
@ -27,6 +28,7 @@ fun AppBarWithBackButtonAndIcon(
onBackClick = onBackClick,
modifier = modifier,
text = text,
subtitle = subtitle,
backIconRes = backIconRes,
backgroundColor = backgroundColor,
iconContent = {

View file

@ -1,10 +1,10 @@
package com.tangem.core.ui.components.appbar
import androidx.annotation.DrawableRes
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
@ -37,6 +37,7 @@ fun AppBarWithBackButtonAndIconContent(
onBackClick: () -> Unit,
modifier: Modifier = Modifier,
text: String? = null,
subtitle: String? = null,
@DrawableRes backIconRes: Int? = null,
backIconTint: Color = TangemTheme.colors.icon.primary1,
backgroundColor: Color = TangemTheme.colors.background.secondary,
@ -46,7 +47,7 @@ fun AppBarWithBackButtonAndIconContent(
modifier = modifier
.background(color = backgroundColor)
.fillMaxWidth()
.padding(all = TangemTheme.dimens.spacing16),
.padding(horizontal = TangemTheme.dimens.spacing16),
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
verticalAlignment = Alignment.CenterVertically,
) {
@ -54,6 +55,7 @@ fun AppBarWithBackButtonAndIconContent(
painter = painterResource(backIconRes ?: R.drawable.ic_back_24),
contentDescription = null,
modifier = Modifier
.padding(vertical = TangemTheme.dimens.spacing16)
.size(size = TangemTheme.dimens.size24)
.clickable(
interactionSource = remember { MutableInteractionSource() },
@ -61,20 +63,37 @@ fun AppBarWithBackButtonAndIconContent(
) { onBackClick() },
tint = backIconTint,
)
AnimatedContent(
targetState = text,
modifier = Modifier.weight(1f),
transitionSpec = { fadeIn().togetherWith(fadeOut()) },
label = "Toolbar title change",
Column(
verticalArrangement = Arrangement.Center,
modifier = Modifier.weight(1f)
.animateContentSize(),
) {
if (!it.isNullOrBlank()) {
AnimatedVisibility(
visible = !text.isNullOrBlank(),
enter = fadeIn(),
exit = fadeOut(),
label = "Toolbar title change",
) {
Text(
text = it,
text = text.orEmpty(),
color = TangemTheme.colors.text.primary1,
maxLines = 1,
style = TangemTheme.typography.subtitle1,
)
}
AnimatedVisibility(
visible = !subtitle.isNullOrBlank(),
enter = fadeIn(),
exit = fadeOut(),
label = "Toolbar subtitle change",
) {
Text(
text = subtitle.orEmpty(),
color = TangemTheme.colors.text.secondary,
maxLines = 1,
style = TangemTheme.typography.caption2,
)
}
}
iconContent()
}
@ -111,6 +130,7 @@ private fun PreviewAppBarWithBackButtonAndIconInDarkTheme() {
TangemTheme(isDark = true) {
AppBarWithBackButtonAndIconContent(
text = "Title",
subtitle = "Subtitle",
onBackClick = {},
iconContent = {
Row {

View file

@ -8,7 +8,7 @@ import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.graphics.Color
import com.tangem.core.ui.res.TangemTheme
internal object TangemButtonsDefaults {
object TangemButtonsDefaults {
val elevation: ButtonElevation
@Composable

View file

@ -1,7 +1,9 @@
package com.tangem.core.ui.components.fields
import androidx.annotation.FloatRange
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
@ -12,7 +14,12 @@ import androidx.compose.ui.Alignment.Companion.TopCenter
import androidx.compose.ui.Alignment.Companion.TopStart
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.ParagraphIntrinsics
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.createFontFamilyResolver
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDirection
@ -57,51 +64,77 @@ fun AmountTextField(
keyboardType = KeyboardType.Number,
),
keyboardActions: KeyboardActions = KeyboardActions.Default,
isAutoResize: Boolean = false,
@FloatRange(from = 0.0, to = 1.0, fromInclusive = false, toInclusive = false)
reduceFactor: Double = 0.9,
) {
val decimalFormat = rememberDecimalFormat()
val visualTransformation = remember { AmountVisualTransformation(decimals, symbol, decimalFormat) }
val placeholderTextAlign = if (placeholderAlignment == TopCenter) {
TextAlign.Center
} else {
TextAlign.Start
}
SimpleTextField(
value = value,
onValueChange = { newText ->
if (decimalFormat.isValidSymbols(newText)) {
val trimmed = decimalFormat.getValidatedNumberWithFixedDecimals(newText, decimals)
onValueChange(trimmed)
BoxWithConstraints(modifier = modifier) {
var fontSize = textStyle.fontSize
if (isAutoResize) {
val calculateIntrinsics = @Composable {
val transformedText = visualTransformation.filter(AnnotatedString(value)).text.text
ParagraphIntrinsics(
text = transformedText,
style = textStyle.copy(fontSize = fontSize),
density = LocalDensity.current,
fontFamilyResolver = createFontFamilyResolver(LocalContext.current),
)
}
},
modifier = modifier
.background(TangemTheme.colors.background.action),
textStyle = textStyle.copy(textDirection = TextDirection.ContentOrLtr),
color = color,
keyboardOptions = keyboardOptions,
keyboardActions = keyboardActions,
singleLine = true,
visualTransformation = AmountVisualTransformation(decimals, symbol, decimalFormat),
decorationBox = { innerTextField ->
Box {
if (value.isBlank() && showPlaceholder) {
val placeholder = if (symbol != null) {
decimalFormat.defaultFormat().plus(" $symbol")
} else {
decimalFormat.defaultFormat()
}
Text(
text = placeholder,
style = textStyle.copy(textDirection = TextDirection.ContentOrLtr),
color = TangemTheme.colors.text.disabled,
textAlign = placeholderTextAlign,
modifier = Modifier
.align(placeholderAlignment),
)
var intrinsics = calculateIntrinsics()
with(LocalDensity.current) {
while (intrinsics.maxIntrinsicWidth > maxWidth.toPx()) {
fontSize *= reduceFactor
intrinsics = calculateIntrinsics()
}
innerTextField()
}
},
)
}
SimpleTextField(
value = value,
onValueChange = { newText ->
if (decimalFormat.isValidSymbols(newText)) {
val trimmed = decimalFormat.getValidatedNumberWithFixedDecimals(newText, decimals)
onValueChange(trimmed)
}
},
textStyle = textStyle.copy(
fontSize = fontSize,
textDirection = TextDirection.ContentOrLtr,
textAlign = TextAlign.Center,
),
color = color,
keyboardOptions = keyboardOptions,
keyboardActions = keyboardActions,
singleLine = true,
visualTransformation = AmountVisualTransformation(decimals, symbol, decimalFormat),
modifier = Modifier.background(TangemTheme.colors.background.action),
decorationBox = { innerTextField ->
Box {
if (value.isBlank() && showPlaceholder) {
val placeholder = if (symbol != null) {
decimalFormat.defaultFormat().plus(" $symbol")
} else {
decimalFormat.defaultFormat()
}
Text(
text = placeholder,
style = textStyle.copy(textDirection = TextDirection.ContentOrLtr),
color = TangemTheme.colors.text.disabled,
textAlign = placeholderTextAlign,
modifier = Modifier.align(placeholderAlignment),
)
}
innerTextField()
}
},
)
}
}
private fun DecimalFormat.isValidSymbols(text: String): Boolean {