Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-19 16:56:24 +04:00
commit d12c3b8b34
5 changed files with 217 additions and 4 deletions

View file

@ -0,0 +1,106 @@
package com.tangem.core.ui.components.buttons
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
/**
* Small button config
*
* @property text text
* @property onClick lambda be invoked when action component is clicked
*
*/
data class SmallButtonConfig(
val text: TextReference,
val onClick: () -> Unit,
)
/**
* Primary small button
* [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=68%3A20&mode=design&t=fjwUkRtMUA4Q4s5r-1)
*
* @property config Config, containing parameters for a button
*/
@Composable
fun PrimarySmallButton(config: SmallButtonConfig, modifier: Modifier = Modifier) {
SmallButton(config = config, isPrimary = true, modifier = modifier)
}
/**
* Secondary small button
* [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=68%3A20&mode=design&t=fjwUkRtMUA4Q4s5r-1)
*
* @property config Config, containing parameters for a button
*/
@Composable
fun SecondarySmallButton(config: SmallButtonConfig, modifier: Modifier = Modifier) {
SmallButton(config = config, isPrimary = false, modifier = modifier)
}
@Composable
private fun SmallButton(config: SmallButtonConfig, isPrimary: Boolean, modifier: Modifier = Modifier) {
val shape = RoundedCornerShape(size = TangemTheme.dimens.radius16)
Box(
modifier = modifier
.defaultMinSize(minWidth = TangemTheme.dimens.size46, minHeight = TangemTheme.dimens.size24)
.clip(shape)
.background(
color = if (isPrimary) TangemTheme.colors.button.primary else TangemTheme.colors.button.secondary,
shape = shape,
)
.clickable(enabled = true, onClick = config.onClick)
.padding(
vertical = TangemTheme.dimens.spacing2,
),
contentAlignment = Alignment.Center,
) {
Text(
text = config.text.resolveReference(),
color = if (isPrimary) TangemTheme.colors.text.primary2 else TangemTheme.colors.text.primary1,
maxLines = 1,
style = TangemTheme.typography.button,
)
}
}
@Preview(showBackground = true)
@Composable
private fun Preview_SmallButton_Light() {
TangemTheme(isDark = false) {
ButtonsSample()
}
}
@Preview(showBackground = true)
@Composable
private fun Preview_SmallButton_Dark() {
TangemTheme(isDark = true) {
ButtonsSample()
}
}
@Composable
private fun ButtonsSample() {
Column(
modifier = Modifier.background(TangemTheme.colors.background.primary),
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
) {
val config = SmallButtonConfig(
text = TextReference.Str(value = "Add"),
onClick = {},
)
PrimarySmallButton(config = config)
SecondarySmallButton(config = config.copy(text = TextReference.Str(value = "Add")))
}
}

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#1E1E1E"
android:pathData="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20ZM12,2C10.687,2 9.386,2.259 8.173,2.761C6.96,3.264 5.858,4 4.929,4.929C3.054,6.804 2,9.348 2,12C2,14.652 3.054,17.196 4.929,19.071C5.858,20 6.96,20.736 8.173,21.239C9.386,21.741 10.687,22 12,22C14.652,22 17.196,20.946 19.071,19.071C20.946,17.196 22,14.652 22,12C22,10.687 21.741,9.386 21.239,8.173C20.736,6.96 20,5.858 19.071,4.929C18.142,4 17.04,3.264 15.827,2.761C14.614,2.259 13.313,2 12,2ZM11,17H13V11H11V17Z" />
</vector>

View file

@ -0,0 +1,5 @@
package com.tangem.managetokens.presentation.managetokens.state
internal enum class TokenButtonType {
ADD, EDIT, NOT_AVAILABLE
}

View file

@ -14,6 +14,8 @@ import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.res.TangemTheme
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
/**
* A chart with a solid line and gradient underneath. It can accept values of any range and number.
@ -22,7 +24,7 @@ import com.tangem.core.ui.res.TangemTheme
* @param values a list of float values for a chart.
**/
@Composable
fun PriceChangesChart(values: List<Float>, modifier: Modifier = Modifier) {
fun PriceChangesChart(values: ImmutableList<Float>, modifier: Modifier = Modifier) {
Row(modifier = modifier) {
if (values.size < 2) return // escape without drawing when there are not enough points
@ -39,7 +41,7 @@ fun PriceChangesChart(values: List<Float>, modifier: Modifier = Modifier) {
}
@Composable
private fun Chart(list: List<Float>, lineColor: Color, gradient: Brush, modifier: Modifier = Modifier) {
private fun Chart(list: ImmutableList<Float>, lineColor: Color, gradient: Brush, modifier: Modifier = Modifier) {
val max = list.max()
val min = list.min()
val zipList: List<Pair<Float, Float>> = list.zipWithNext()
@ -105,7 +107,7 @@ private fun getValuePercentageForRange(value: Float, max: Float, min: Float): Fl
private fun Chart_Positive_Preview() {
TangemTheme(isDark = true) {
PriceChangesChart(
listOf(1f, 2f, 4f, 1f, 5f),
persistentListOf(1f, 2f, 4f, 1f, 5f),
)
}
}
@ -115,7 +117,7 @@ private fun Chart_Positive_Preview() {
private fun Chart_Negative_Preview() {
TangemTheme(isDark = true) {
PriceChangesChart(
listOf(10f, 2f, 4f, 1f, 5f),
persistentListOf(10f, 2f, 4f, 1f, 5f),
)
}
}

View file

@ -0,0 +1,90 @@
package com.tangem.managetokens.presentation.managetokens.ui.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.material.Icon
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.tangem.core.ui.components.buttons.PrimarySmallButton
import com.tangem.core.ui.components.buttons.SecondarySmallButton
import com.tangem.core.ui.components.buttons.SmallButtonConfig
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.managetokens.impl.R
import com.tangem.managetokens.presentation.managetokens.state.TokenButtonType
@Composable
internal fun TokenButton(type: TokenButtonType, onClick: () -> Unit, modifier: Modifier = Modifier) {
when (type) {
TokenButtonType.ADD -> PrimarySmallButton(
config = SmallButtonConfig(
text = resourceReference(R.string.manage_tokens_add),
onClick = onClick,
),
modifier = modifier,
)
TokenButtonType.EDIT -> SecondarySmallButton(
config = SmallButtonConfig(
text = resourceReference(R.string.manage_tokens_edit),
onClick = onClick,
),
modifier = modifier,
)
TokenButtonType.NOT_AVAILABLE -> {
Box(
modifier = modifier
.size(height = TangemTheme.dimens.size24, width = TangemTheme.dimens.size46)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(
bounded = false,
radius = TangemTheme.dimens.size20,
),
onClick = onClick,
),
contentAlignment = Alignment.Center,
) {
Icon(
modifier = Modifier
.size(TangemTheme.dimens.size20),
painter = painterResource(id = R.drawable.ic_information_24),
tint = TangemTheme.colors.icon.informative,
contentDescription = null,
)
}
}
}
}
@Preview(backgroundColor = 0xffffff, showBackground = true)
@Composable
private fun TokenButton_Light_Preview(@PreviewParameter(TokenButtonTypeProvider::class) type: TokenButtonType) {
TangemTheme(isDark = false) {
TokenButton(type = type, {})
}
}
@Preview(showBackground = true)
@Composable
private fun TokenButton_Dark_Preview(@PreviewParameter(TokenButtonTypeProvider::class) type: TokenButtonType) {
TangemTheme(isDark = true) {
TokenButton(type = type, {})
}
}
private class TokenButtonTypeProvider : PreviewParameterProvider<TokenButtonType> {
override val values = sequenceOf(
TokenButtonType.ADD,
TokenButtonType.EDIT,
TokenButtonType.NOT_AVAILABLE,
)
}