Updated on 2026-08-14

This commit is contained in:
Tangem 2025-12-24 18:45:02 +05:00
commit 072d04125d
17 changed files with 1465 additions and 11 deletions

View file

@ -0,0 +1,125 @@
package com.tangem.core.ui.ds.button
import android.content.res.Configuration
import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
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.R
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
/**
* [Accent Tangem button](https://www.figma.com/design/RU7AIgwHtGdMfy83T5UOoR/Core-Library?node-id=8004-26798)
*
* @param onClick Lambda to be invoked when the button is clicked.
* @param modifier Modifier to be applied to the button.
* @param text TextReference for the button label.
* @param iconRes Drawable resource ID for the icon to be displayed in the button.
* @param iconPosition Position of the icon (Start or End).
* @param enabled Boolean indicating whether the button is enabled.
* @param size TangemButtonSize defining the size of the button.
* @param state TangemButtonState defining the current state of the button.
* @param shape TangemButtonShape defining the shape of the button.
*
[REDACTED_AUTHOR]
*/
@Composable
fun AccentTangemButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
text: TextReference? = null,
@DrawableRes iconRes: Int? = null,
iconPosition: TangemButtonIconPosition = TangemButtonIconPosition.Start,
enabled: Boolean = true,
size: TangemButtonSize = TangemButtonSize.X15,
state: TangemButtonState = TangemButtonState.Default,
shape: TangemButtonShape = TangemButtonShape.Default,
) {
TangemButtonInternal(
onClick = onClick,
modifier = modifier
.clip(shape.toShape(size))
.then(
when (state) {
TangemButtonState.Disabled,
TangemButtonState.Default,
-> Modifier.background(TangemTheme.colors2.button.backgroundPositive)
TangemButtonState.Loading,
TangemButtonState.Pressed,
-> Modifier
.background(TangemTheme.colors2.button.backgroundPositive)
.background(TangemTheme.colors2.overlay.overlaySecondary)
},
),
text = text,
contentColor = TangemTheme.colors2.text.neutral.primaryInvertedConstant,
iconRes = iconRes,
enabled = enabled,
size = size,
state = state,
iconPosition = iconPosition,
)
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 480)
@Preview(showBackground = true, widthDp = 480, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun AccentTangemButton_Preview(
@PreviewParameter(AccentTangemButtonPreviewProvider::class) params: TangemButtonState,
) {
TangemThemePreviewRedesign {
Row(
horizontalArrangement = Arrangement.spacedBy(21.dp),
modifier = Modifier
.background(TangemTheme.colors2.surface.level1)
.padding(8.dp),
) {
repeat(4) { yIndex ->
val shape = if (yIndex < 2) TangemButtonShape.Default else TangemButtonShape.Rounded
val text = if (yIndex % 2 == 1) null else stringReference("Button")
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
repeat(2) { xIndex ->
val iconPosition = if (xIndex == 1) {
TangemButtonIconPosition.Start
} else {
TangemButtonIconPosition.End
}
AccentTangemButton(
onClick = {},
text = text,
size = TangemButtonSize.X15,
shape = shape,
iconPosition = iconPosition,
iconRes = R.drawable.ic_tangem_24,
state = params,
)
}
}
}
}
}
}
private class AccentTangemButtonPreviewProvider : PreviewParameterProvider<TangemButtonState> {
override val values: Sequence<TangemButtonState>
get() = sequenceOf(
TangemButtonState.Default,
TangemButtonState.Pressed,
TangemButtonState.Loading,
TangemButtonState.Disabled,
)
}
// endregion

View file

@ -0,0 +1,111 @@
package com.tangem.core.ui.ds.button
import android.content.res.Configuration
import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
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.R
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
/**
* [Ghost Tangem button](https://www.figma.com/design/RU7AIgwHtGdMfy83T5UOoR/Core-Library?node-id=5854-4804)
*
* @param onClick Lambda to be invoked when the button is clicked.
* @param modifier Modifier to be applied to the button.
* @param text TextReference for the button label.
* @param iconRes Drawable resource ID for the icon to be displayed in the button.
* @param iconPosition Position of the icon (Start or End).
* @param enabled Boolean indicating whether the button is enabled.
* @param size TangemButtonSize defining the size of the button.
* @param state TangemButtonState defining the current state of the button.
*
[REDACTED_AUTHOR]
*/
@Composable
fun GhostTangemButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
text: TextReference? = null,
@DrawableRes iconRes: Int? = null,
enabled: Boolean = true,
size: TangemButtonSize = TangemButtonSize.X15,
state: TangemButtonState = TangemButtonState.Default,
iconPosition: TangemButtonIconPosition = TangemButtonIconPosition.Start,
) {
val contentColor = when (state) {
TangemButtonState.Disabled -> TangemTheme.colors2.text.status.disabled
else -> TangemTheme.colors2.text.neutral.primary
}
TangemButtonInternal(
onClick = onClick,
modifier = modifier,
text = text,
contentColor = contentColor,
enabled = enabled,
size = size,
state = state,
iconPosition = iconPosition,
iconRes = iconRes,
)
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 480)
@Preview(showBackground = true, widthDp = 480, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun GhostTangemButton_Preview(
@PreviewParameter(GhostTangemButtonPreviewProvider::class) params: TangemButtonState,
) {
TangemThemePreviewRedesign {
Row(
horizontalArrangement = Arrangement.spacedBy(21.dp),
modifier = Modifier
.background(TangemTheme.colors2.surface.level1)
.padding(8.dp),
) {
repeat(4) { yIndex ->
val text = if (yIndex % 2 == 1) null else stringReference("Button")
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
repeat(2) { xIndex ->
val iconPosition = if (xIndex == 1) {
TangemButtonIconPosition.Start
} else {
TangemButtonIconPosition.End
}
GhostTangemButton(
onClick = {},
text = text,
size = TangemButtonSize.X15,
iconPosition = iconPosition,
iconRes = R.drawable.ic_tangem_24,
state = params,
)
}
}
}
}
}
}
private class GhostTangemButtonPreviewProvider : PreviewParameterProvider<TangemButtonState> {
override val values: Sequence<TangemButtonState>
get() = sequenceOf(
TangemButtonState.Default,
TangemButtonState.Pressed,
TangemButtonState.Loading,
TangemButtonState.Disabled,
)
}
// endregion

View file

@ -0,0 +1,132 @@
package com.tangem.core.ui.ds.button
import android.content.res.Configuration
import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
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.R
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
/**
* [Outline Tangem button](https://www.figma.com/design/RU7AIgwHtGdMfy83T5UOoR/Core-Library?node-id=5854-4800)
*
* @param onClick Lambda to be invoked when the button is clicked.
* @param modifier Modifier to be applied to the button.
* @param text TextReference for the button label.
* @param iconRes Drawable resource ID for the icon to be displayed in the button.
* @param iconPosition Position of the icon (Start or End).
* @param enabled Boolean indicating whether the button is enabled.
* @param size TangemButtonSize defining the size of the button.
* @param state TangemButtonState defining the current state of the button.
* @param shape TangemButtonShape defining the shape of the button.
*
[REDACTED_AUTHOR]
*/
@Composable
fun OutlineTangemButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
text: TextReference? = null,
@DrawableRes iconRes: Int? = null,
iconPosition: TangemButtonIconPosition = TangemButtonIconPosition.Start,
enabled: Boolean = true,
size: TangemButtonSize = TangemButtonSize.X15,
state: TangemButtonState = TangemButtonState.Default,
shape: TangemButtonShape = TangemButtonShape.Default,
) {
val backgroundModifier = when (state) {
TangemButtonState.Loading,
TangemButtonState.Pressed,
TangemButtonState.Disabled,
TangemButtonState.Default,
-> Modifier
.background(TangemTheme.colors2.surface.level1)
.border(
width = 1.dp,
color = TangemTheme.colors2.border.neutral.primary,
shape = shape.toShape(size),
)
}
val contentColor = when (state) {
TangemButtonState.Disabled -> TangemTheme.colors2.text.status.disabled
else -> TangemTheme.colors2.text.neutral.primary
}
TangemButtonInternal(
onClick = onClick,
modifier = modifier
.clip(shape.toShape(size))
.then(backgroundModifier),
text = text,
contentColor = contentColor,
iconRes = iconRes,
enabled = enabled,
size = size,
state = state,
iconPosition = iconPosition,
)
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 480)
@Preview(showBackground = true, widthDp = 480, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun OutlineTangemButton_Preview(
@PreviewParameter(OutlineTangemButtonPreviewProvider::class) params: TangemButtonState,
) {
TangemThemePreviewRedesign {
Row(
horizontalArrangement = Arrangement.spacedBy(21.dp),
modifier = Modifier
.background(TangemTheme.colors2.surface.level1)
.padding(8.dp),
) {
repeat(4) { yIndex ->
val shape = if (yIndex < 2) TangemButtonShape.Default else TangemButtonShape.Rounded
val text = if (yIndex % 2 == 1) null else stringReference("Button")
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
repeat(2) { xIndex ->
val iconPosition = if (xIndex == 0) {
TangemButtonIconPosition.Start
} else {
TangemButtonIconPosition.End
}
OutlineTangemButton(
onClick = {},
text = text,
size = TangemButtonSize.X15,
shape = shape,
iconPosition = iconPosition,
iconRes = R.drawable.ic_tangem_24,
state = params,
)
}
}
}
}
}
}
private class OutlineTangemButtonPreviewProvider : PreviewParameterProvider<TangemButtonState> {
override val values: Sequence<TangemButtonState>
get() = sequenceOf(
TangemButtonState.Default,
TangemButtonState.Pressed,
TangemButtonState.Loading,
TangemButtonState.Disabled,
)
}
// endregion

View file

@ -0,0 +1,127 @@
package com.tangem.core.ui.ds.button
import android.content.res.Configuration
import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
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.R
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
/**
* [Primary Inverse Tangem button](https://www.figma.com/design/RU7AIgwHtGdMfy83T5UOoR/Core-Library?node-id=7545-78314)
*
* @param onClick Lambda to be invoked when the button is clicked.
* @param modifier Modifier to be applied to the button.
* @param text TextReference for the button label.
* @param iconRes Drawable resource ID for the icon to be displayed in the button.
* @param iconPosition Position of the icon (Start or End).
* @param enabled Boolean indicating whether the button is enabled.
* @param size TangemButtonSize defining the size of the button.
* @param state TangemButtonState defining the current state of the button.
* @param shape TangemButtonShape defining the shape of the button.
*
[REDACTED_AUTHOR]
*/
@Composable
fun PrimaryInverseTangemButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
text: TextReference? = null,
@DrawableRes iconRes: Int? = null,
iconPosition: TangemButtonIconPosition = TangemButtonIconPosition.Start,
enabled: Boolean = true,
size: TangemButtonSize = TangemButtonSize.X15,
state: TangemButtonState = TangemButtonState.Default,
shape: TangemButtonShape = TangemButtonShape.Default,
) {
val backgroundModifier = when (state) {
TangemButtonState.Default -> Modifier.background(TangemTheme.colors2.button.backgroundPrimaryInverse)
TangemButtonState.Disabled -> Modifier.background(TangemTheme.colors2.button.backgroundDisabled)
TangemButtonState.Loading,
TangemButtonState.Pressed,
-> Modifier
.background(TangemTheme.colors2.button.backgroundPrimaryInverse)
.background(TangemTheme.colors2.overlay.overlayPrimary)
}
val contentColor = when (state) {
TangemButtonState.Disabled -> TangemTheme.colors2.text.status.disabled
else -> TangemTheme.colors2.text.neutral.primary
}
TangemButtonInternal(
onClick = onClick,
modifier = modifier
.clip(shape.toShape(size))
.then(backgroundModifier),
text = text,
contentColor = contentColor,
enabled = enabled,
size = size,
state = state,
iconPosition = iconPosition,
iconRes = iconRes,
)
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 480)
@Preview(showBackground = true, widthDp = 480, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun PrimaryInverseTangemButton_Preview(
@PreviewParameter(PrimaryInverseTangemButtonPreviewProvider::class) params: TangemButtonState,
) {
TangemThemePreviewRedesign {
Row(
horizontalArrangement = Arrangement.spacedBy(21.dp),
modifier = Modifier
.background(TangemTheme.colors2.surface.level2)
.padding(8.dp),
) {
repeat(4) { yIndex ->
val shape = if (yIndex < 2) TangemButtonShape.Default else TangemButtonShape.Rounded
val text = if (yIndex % 2 == 1) null else stringReference("Button")
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
repeat(2) { xIndex ->
val iconPosition = if (xIndex == 0) {
TangemButtonIconPosition.Start
} else {
TangemButtonIconPosition.End
}
PrimaryInverseTangemButton(
onClick = {},
text = text,
size = TangemButtonSize.X15,
shape = shape,
iconPosition = iconPosition,
iconRes = R.drawable.ic_tangem_24,
state = params,
)
}
}
}
}
}
}
private class PrimaryInverseTangemButtonPreviewProvider : PreviewParameterProvider<TangemButtonState> {
override val values: Sequence<TangemButtonState>
get() = sequenceOf(
TangemButtonState.Default,
TangemButtonState.Pressed,
TangemButtonState.Loading,
TangemButtonState.Disabled,
)
}
// endregion

View file

@ -0,0 +1,122 @@
package com.tangem.core.ui.ds.button
import android.content.res.Configuration
import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
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.R
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
/**
* [Primary Tangem button](https://www.figma.com/design/RU7AIgwHtGdMfy83T5UOoR/Core-Library?node-id=5854-4732&t=euYo1qCxPlQl3Fa6-4)
*
* @param onClick Lambda to be invoked when the button is clicked.
* @param modifier Modifier to be applied to the button.
* @param text TextReference for the button label.
* @param iconRes Drawable resource ID for the icon to be displayed in the button.
* @param iconPosition Position of the icon (Start or End).
* @param enabled Boolean indicating whether the button is enabled.
* @param size TangemButtonSize defining the size of the button.
* @param state TangemButtonState defining the current state of the button.
* @param shape TangemButtonShape defining the shape of the button.
*
[REDACTED_AUTHOR]
*/
@Composable
fun PrimaryTangemButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
text: TextReference? = null,
@DrawableRes iconRes: Int? = null,
iconPosition: TangemButtonIconPosition = TangemButtonIconPosition.Start,
enabled: Boolean = true,
size: TangemButtonSize = TangemButtonSize.X15,
state: TangemButtonState = TangemButtonState.Default,
shape: TangemButtonShape = TangemButtonShape.Default,
) {
val backgroundModifier = when (state) {
TangemButtonState.Loading,
TangemButtonState.Default,
-> Modifier.background(TangemTheme.colors2.button.backgroundPrimary)
TangemButtonState.Disabled -> Modifier.background(TangemTheme.colors2.button.backgroundDisabled)
TangemButtonState.Pressed -> Modifier
.background(TangemTheme.colors2.button.backgroundPrimary)
.background(TangemTheme.colors2.overlay.overlaySecondary)
}
val contentColor = when (state) {
TangemButtonState.Disabled -> TangemTheme.colors2.text.status.disabled
else -> TangemTheme.colors2.text.neutral.primaryInverted
}
TangemButtonInternal(
onClick = onClick,
modifier = modifier
.clip(shape.toShape(size))
.then(backgroundModifier),
text = text,
contentColor = contentColor,
enabled = enabled,
size = size,
state = state,
iconPosition = iconPosition,
iconRes = iconRes,
)
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 480)
@Preview(showBackground = true, widthDp = 480, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun PrimaryTangemButton_Preview(
@PreviewParameter(PrimaryTangemButtonPreviewProvider::class) params: TangemButtonState,
) {
TangemThemePreviewRedesign {
Row(
horizontalArrangement = Arrangement.spacedBy(21.dp),
modifier = Modifier
.background(TangemTheme.colors2.surface.level1)
.padding(8.dp),
) {
repeat(4) { yIndex ->
val shape = if (yIndex < 2) TangemButtonShape.Default else TangemButtonShape.Rounded
val text = if (yIndex % 2 == 1) null else stringReference("Button")
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
repeat(TangemButtonIconPosition.entries.size) { xIndex ->
PrimaryTangemButton(
onClick = {},
text = text,
size = TangemButtonSize.X15,
shape = shape,
iconPosition = TangemButtonIconPosition.entries[xIndex],
iconRes = R.drawable.ic_tangem_24,
state = params,
)
}
}
}
}
}
}
private class PrimaryTangemButtonPreviewProvider : PreviewParameterProvider<TangemButtonState> {
override val values: Sequence<TangemButtonState>
get() = sequenceOf(
TangemButtonState.Default,
TangemButtonState.Pressed,
TangemButtonState.Loading,
TangemButtonState.Disabled,
)
}
// endregion

View file

@ -0,0 +1,125 @@
package com.tangem.core.ui.ds.button
import android.content.res.Configuration
import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
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.R
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
/**
* [Secondary Tangem button](https://www.figma.com/design/RU7AIgwHtGdMfy83T5UOoR/Core-Library?node-id=5854-4796)
*
* @param onClick Lambda to be invoked when the button is clicked.
* @param modifier Modifier to be applied to the button.
* @param text TextReference for the button label.
* @param iconRes Drawable resource ID for the icon to be displayed in the button.
* @param iconPosition Position of the icon (Start or End).
* @param enabled Boolean indicating whether the button is enabled.
* @param size TangemButtonSize defining the size of the button.
* @param state TangemButtonState defining the current state of the button.
* @param shape TangemButtonShape defining the shape of the button.
*
[REDACTED_AUTHOR]
*/
@Composable
fun SecondaryTangemButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
text: TextReference? = null,
@DrawableRes iconRes: Int? = null,
iconPosition: TangemButtonIconPosition = TangemButtonIconPosition.Start,
enabled: Boolean = true,
size: TangemButtonSize = TangemButtonSize.X15,
state: TangemButtonState = TangemButtonState.Default,
shape: TangemButtonShape = TangemButtonShape.Default,
) {
val backgroundModifier = when (state) {
TangemButtonState.Loading,
TangemButtonState.Default,
-> Modifier.background(TangemTheme.colors2.button.backgroundSecondary)
TangemButtonState.Disabled -> Modifier.background(TangemTheme.colors2.button.backgroundDisabled)
TangemButtonState.Pressed -> Modifier.background(TangemTheme.colors2.overlay.overlayPrimary)
}
val contentColor = when (state) {
TangemButtonState.Disabled -> TangemTheme.colors2.text.status.disabled
else -> TangemTheme.colors2.text.neutral.primary
}
TangemButtonInternal(
onClick = onClick,
modifier = modifier
.clip(shape.toShape(size))
.then(backgroundModifier),
text = text,
contentColor = contentColor,
iconRes = iconRes,
enabled = enabled,
size = size,
state = state,
iconPosition = iconPosition,
)
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 480)
@Preview(showBackground = true, widthDp = 480, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun SecondaryTangemButton_Preview(
@PreviewParameter(SecondaryTangemButtonPreviewProvider::class) params: TangemButtonState,
) {
TangemThemePreviewRedesign {
Row(
horizontalArrangement = Arrangement.spacedBy(21.dp),
modifier = Modifier
.background(TangemTheme.colors2.surface.level1)
.padding(8.dp),
) {
repeat(4) { yIndex ->
val shape = if (yIndex < 2) TangemButtonShape.Default else TangemButtonShape.Rounded
val text = if (yIndex % 2 == 1) null else stringReference("Button")
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
repeat(2) { xIndex ->
val iconPosition = if (xIndex == 0) {
TangemButtonIconPosition.Start
} else {
TangemButtonIconPosition.End
}
SecondaryTangemButton(
onClick = {},
text = text,
size = TangemButtonSize.X15,
shape = shape,
iconPosition = iconPosition,
iconRes = R.drawable.ic_tangem_24,
state = params,
)
}
}
}
}
}
}
private class SecondaryTangemButtonPreviewProvider : PreviewParameterProvider<TangemButtonState> {
override val values: Sequence<TangemButtonState>
get() = sequenceOf(
TangemButtonState.Default,
TangemButtonState.Pressed,
TangemButtonState.Loading,
TangemButtonState.Disabled,
)
}
// endregion

View file

@ -0,0 +1,256 @@
package com.tangem.core.ui.ds.button
import androidx.annotation.DrawableRes
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.TextAutoSize
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.clickableSingle
import com.tangem.core.ui.extensions.conditionalCompose
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.BaseButtonTestTags
/**
* A customizable button component that supports text, icons, and different states.
*
* @param onClick Lambda to be invoked when the button is clicked.
* @param modifier Modifier to be applied to the button.
* @param text TextReference for the button label.
* @param iconRes Drawable resource ID for the icon to be displayed in the button.
* @param iconPosition Position of the icon (Start or End).
* @param enabled Boolean indicating whether the button is enabled.
* @param contentColor Color of the button content (text and icon).
* @param size TangemButtonSize defining the size of the button.
* @param state TangemButtonState defining the current state of the button.
*
[REDACTED_AUTHOR]
*/
@Composable
internal fun TangemButtonInternal(
onClick: () -> Unit,
modifier: Modifier = Modifier,
text: TextReference? = null,
@DrawableRes iconRes: Int? = null,
iconPosition: TangemButtonIconPosition = TangemButtonIconPosition.Start,
enabled: Boolean = true,
contentColor: Color = TangemTheme.colors2.text.neutral.primary,
size: TangemButtonSize = TangemButtonSize.X15,
state: TangemButtonState = TangemButtonState.Default,
) {
Row(
modifier = modifier
.testTag(BaseButtonTestTags.BUTTON)
.height(size.toHeightDp())
.conditionalCompose(text == null) {
width(size.toHeightDp())
}
.clickableSingle(enabled = enabled, onClick = onClick, role = Role.Button)
.conditionalCompose(text != null) {
padding(horizontal = size.toPaddingDp())
}
.animateContentSize(),
horizontalArrangement = Arrangement.spacedBy(4.dp, Alignment.CenterHorizontally),
verticalAlignment = Alignment.CenterVertically,
) {
AnimatedVisibility(
visible = iconRes != null && iconPosition == TangemButtonIconPosition.Start,
modifier = Modifier.size(size = size.toContentSize()),
) {
val wrappedIconRes = remember(this) { requireNotNull(iconRes) }
TangemButtonIcon(iconRes = wrappedIconRes, state = state, iconColor = contentColor, size = size)
}
AnimatedVisibility(text != null && state != TangemButtonState.Loading) {
val wrappedText = remember(this) { requireNotNull(text) }
val textStyle = size.toTextStyle()
Text(
text = wrappedText.resolveReference(),
style = textStyle,
color = contentColor,
textAlign = TextAlign.Center,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
autoSize = TextAutoSize.StepBased(
minFontSize = 12.sp,
maxFontSize = textStyle.fontSize,
),
modifier = Modifier.testTag(BaseButtonTestTags.TEXT),
)
}
AnimatedVisibility(
visible = iconRes != null && iconPosition == TangemButtonIconPosition.End,
modifier = Modifier.size(size = size.toContentSize()),
) {
val wrappedIconRes = remember(this) { requireNotNull(iconRes) }
TangemButtonIcon(iconRes = wrappedIconRes, state = state, iconColor = contentColor, size = size)
}
}
}
@Composable
private fun TangemButtonIcon(
@DrawableRes iconRes: Int,
iconColor: Color,
state: TangemButtonState,
size: TangemButtonSize,
) {
AnimatedContent(state) { targetState ->
when (targetState) {
TangemButtonState.Loading -> CircularProgressIndicator(
color = iconColor,
strokeWidth = 2.dp,
strokeCap = StrokeCap.Round,
modifier = Modifier.padding(
when (size) {
TangemButtonSize.X7,
TangemButtonSize.X8,
TangemButtonSize.X9,
TangemButtonSize.X10,
-> 0.5.dp
TangemButtonSize.X12,
TangemButtonSize.X15,
-> 4.5.dp
},
),
)
else -> Icon(
painter = painterResource(id = iconRes),
contentDescription = null,
tint = iconColor,
)
}
}
}
/**
* Defines the shape of the Tangem button.
*/
enum class TangemButtonShape {
Default,
Rounded,
;
@ReadOnlyComposable
@Composable
internal fun toShape(size: TangemButtonSize) = RoundedCornerShape(
when (this) {
Default -> size.toShapeRadius()
Rounded -> 100.dp
},
)
}
/**
* Defines the size of the Tangem button.
*/
enum class TangemButtonSize {
X7,
X8,
X9,
X10,
X12,
X15,
;
@ReadOnlyComposable
@Composable
internal fun toHeightDp() = when (this) {
X7 -> TangemTheme.dimens2.x7
X8 -> TangemTheme.dimens2.x8
X9 -> TangemTheme.dimens2.x9
X10 -> TangemTheme.dimens2.x10
X12 -> TangemTheme.dimens2.x12
X15 -> TangemTheme.dimens2.x15
}
@ReadOnlyComposable
@Composable
internal fun toPaddingDp() = when (this) {
X7 -> TangemTheme.dimens2.x2
X8,
X9,
X10,
-> TangemTheme.dimens2.x3
X12,
X15,
-> TangemTheme.dimens2.x6
}
@ReadOnlyComposable
@Composable
internal fun toContentSize() = when (this) {
X7,
X8,
X9,
X10,
-> TangemTheme.dimens2.x5
X12,
X15,
-> TangemTheme.dimens2.x7
}
@ReadOnlyComposable
@Composable
internal fun toShapeRadius() = when (this) {
X7,
X8,
X9,
X10,
-> TangemTheme.dimens2.x2
X12 -> TangemTheme.dimens2.x3
X15 -> TangemTheme.dimens2.x4
}
@ReadOnlyComposable
@Composable
internal fun toTextStyle(): TextStyle = when (this) {
X7 -> TangemTheme.typography2.bodyRegular14
X8,
X9,
X10,
X12,
X15,
-> TangemTheme.typography2.bodySemibold16
}
}
/**
* Defines the state of the Tangem button.
*/
enum class TangemButtonState {
Default,
Disabled,
Pressed,
Loading,
}
/**
* Defines the position of the icon in the Tangem button.
*/
enum class TangemButtonIconPosition {
Start,
End,
}

View file

@ -54,8 +54,8 @@ fun Modifier.conditional(condition: Boolean, modifier: Modifier.() -> Modifier):
@Composable
fun Modifier.conditionalCompose(
condition: Boolean,
modifier: @Composable Modifier.() -> Modifier = { Modifier },
otherModifier: @Composable Modifier.() -> Modifier = { this },
modifier: @Composable Modifier.() -> Modifier = { Modifier },
): Modifier {
return if (condition) {
then(modifier(Modifier))

View file

@ -18,6 +18,18 @@ object TangemColorPalette {
val Dark6 = Color(0xFF1E1E1E)
// endregion Dark
// region Dark Alpha
val Dark_10 = Color(0x1A1E1E1E)
val Dark_20 = Color(0x331E1E1E)
val Dark_30 = Color(0x4D1E1E1E)
val Dark_40 = Color(0x661E1E1E)
val Dark_50 = Color(0x801E1E1E)
val Dark_60 = Color(0x991E1E1E)
val Dark_70 = Color(0xB31E1E1E)
val Dark_80 = Color(0xCC1E1E1E)
val Dark_90 = Color(0xE61E1E1E)
// endregion Dark Alpha
// region Light
val Light1 = Color(0xFFF5F5F5)
val Light1V2 = Color(0xFFF4F4F4)
@ -27,6 +39,18 @@ object TangemColorPalette {
val Light5 = Color(0xFFB0B0B0)
// endregion Light
// region Light Alpha
val Light_10 = Color(0x1AFFFFFF)
val Light_20 = Color(0x33FFFFFF)
val Light_30 = Color(0x4DFFFFFF)
val Light_40 = Color(0x66FFFFFF)
val Light_50 = Color(0x80FFFFFF)
val Light_60 = Color(0x99FFFFFF)
val Light_70 = Color(0xB3FFFFFF)
val Light_80 = Color(0xCCFFFFFF)
val Light_90 = Color(0xE6FFFFFF)
// endregion Light Alpha
// region Green
val Green = Color(0xFF0C9F3D)
val Meadow = Color(0xFF1ACE80)

View file

@ -162,6 +162,7 @@ class TangemColors2 internal constructor(
backgroundSecondary: Color,
backgroundDisabled: Color,
backgroundPositive: Color,
backgroundPrimaryInverse: Color,
textPrimary: Color,
textSecondary: Color,
textDisabled: Color,
@ -178,6 +179,8 @@ class TangemColors2 internal constructor(
private set
var backgroundPositive by mutableStateOf(backgroundPositive)
private set
var backgroundPrimaryInverse by mutableStateOf(backgroundPrimaryInverse)
private set
var textPrimary by mutableStateOf(textPrimary)
private set
var textSecondary by mutableStateOf(textSecondary)
@ -198,6 +201,7 @@ class TangemColors2 internal constructor(
backgroundSecondary = other.backgroundSecondary
backgroundDisabled = other.backgroundDisabled
backgroundPositive = other.backgroundPositive
backgroundPrimaryInverse = other.backgroundPrimaryInverse
textPrimary = other.textPrimary
textSecondary = other.textSecondary
textDisabled = other.textDisabled

View file

@ -0,0 +1,39 @@
package com.tangem.core.ui.res
import androidx.compose.runtime.Immutable
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@Suppress("ConstructorParameterNaming")
@ConsistentCopyVisibility
@Immutable
data class TangemDimens2 internal constructor(
val x0: Dp = 0.dp,
val x0_5: Dp = 2.dp,
val x1: Dp = 4.dp,
val x2: Dp = 8.dp,
val x2_5: Dp = 10.dp,
val x3: Dp = 12.dp,
val x4: Dp = 16.dp,
val x5: Dp = 20.dp,
val x6: Dp = 24.dp,
val x7: Dp = 28.dp,
val x8: Dp = 32.dp,
val x9: Dp = 36.dp,
val x10: Dp = 40.dp,
val x11: Dp = 44.dp,
val x12: Dp = 48.dp,
val x13: Dp = 52.dp,
val x14: Dp = 56.dp,
val x15: Dp = 60.dp,
val x16: Dp = 64.dp,
val x17: Dp = 68.dp,
val x18: Dp = 72.dp,
val x19: Dp = 76.dp,
val x20: Dp = 80.dp,
val x21: Dp = 84.dp,
val x22: Dp = 88.dp,
val x23: Dp = 92.dp,
val x24: Dp = 96.dp,
val x25: Dp = 100.dp,
)

View file

@ -154,11 +154,21 @@ object TangemTheme {
@ReadOnlyComposable
get() = LocalTangemTypography.current
val typography2: TangemTypography2
@Composable
@ReadOnlyComposable
get() = TangemTypography2(InterFamily)
val dimens: TangemDimens
@Composable
@ReadOnlyComposable
get() = LocalTangemDimens.current
val dimens2: TangemDimens2
@Composable
@ReadOnlyComposable
get() = LocalTangemDimens2.current
val shapes: TangemShapes
@Composable
@ReadOnlyComposable
@ -343,10 +353,18 @@ internal val LocalTangemTypography = staticCompositionLocalOf {
TangemTypography(RobotoFamily)
}
internal val LocalTangemTypography2 = staticCompositionLocalOf {
TangemTypography2(InterFamily)
}
private val LocalTangemDimens = staticCompositionLocalOf {
TangemDimens()
}
private val LocalTangemDimens2 = staticCompositionLocalOf {
TangemDimens2()
}
private val LocalTangemShapes = staticCompositionLocalOf<TangemShapes> {
error("No TangemShapes provided")
}

View file

@ -37,6 +37,32 @@ fun TangemThemePreview(
}
}
@Composable
fun TangemThemePreviewRedesign(
isDark: Boolean? = null,
alwaysShowBottomSheets: Boolean = true,
rtl: Boolean = false,
content: @Composable () -> Unit,
) {
val isDarkTheme = isDark ?: isSystemInDarkTheme()
CompositionLocalProvider(
LocalBottomSheetAlwaysVisible provides alwaysShowBottomSheets,
LocalLayoutDirection provides if (rtl) LayoutDirection.Rtl else LayoutDirection.Ltr,
) {
BoxWithConstraints {
TangemTheme(
isDark = isDarkTheme,
windowSize = rememberWindowSizePreview(maxWidth, maxHeight),
) {
TangemThemeRedesign(
content = content,
)
}
}
}
}
/**
* This is used to make the bottom sheet always visible in the Preview and should be `true` only in the Preview.
* */

View file

@ -1,4 +1,5 @@
@file:Suppress("LongMethod")
package com.tangem.core.ui.res
import androidx.compose.material3.MaterialTheme
@ -22,7 +23,7 @@ fun TangemThemeRedesign(content: @Composable () -> Unit) {
CompositionLocalProvider(
LocalTangemColors provides themeColors,
LocalTangemColors2 provides if (LocalIsInDarkTheme.current) darkThemeColors2() else lightThemeColors2(),
LocalTangemTypography provides TangemTypography(InterFamily),
LocalTangemTypography2 provides TangemTypography2(InterFamily),
LocalRootBackgroundColor provides remember(rootBackgroundColor) { mutableStateOf(rootBackgroundColor) },
) {
content()
@ -97,9 +98,10 @@ private fun lightThemeColors2(): TangemColors2 {
)
val button = TangemColors2.Button(
backgroundPrimary = TangemColorPalette.Dark6,
backgroundSecondary = TangemColorPalette.Dark6.copy(alpha = 0.1f),
backgroundSecondary = TangemColorPalette.Dark_10,
backgroundDisabled = TangemColorPalette.Light3,
backgroundPositive = TangemColorPalette.Azure,
backgroundPrimaryInverse = TangemColorPalette.White,
textSecondary = TangemColorPalette.Dark6,
textPrimary = TangemColorPalette.Light2,
textDisabled = text.neutral.tertiary,
@ -236,9 +238,10 @@ private fun darkThemeColors2(): TangemColors2 {
)
val button = TangemColors2.Button(
backgroundPrimary = TangemColorPalette.Light1V2,
backgroundSecondary = TangemColorPalette.White.copy(alpha = 0.1f),
backgroundSecondary = TangemColorPalette.Light_10,
backgroundDisabled = TangemColorPalette.Dark5,
backgroundPositive = TangemColorPalette.Azure,
backgroundPrimaryInverse = TangemColorPalette.Light_10,
textSecondary = TangemColorPalette.Light4,
textPrimary = TangemColorPalette.Dark4,
textDisabled = text.neutral.secondary,

View file

@ -4,7 +4,6 @@ import androidx.compose.runtime.Immutable
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.LineHeightStyle
import androidx.compose.ui.unit.TextUnit
@ -17,11 +16,6 @@ internal val RobotoFamily = FontFamily(
Font(R.font.roboto_medium, FontWeight.Medium),
)
internal val InterFamily = FontFamily(
Font(R.font.inter_regular),
Font(R.font.inter_italic, style = FontStyle.Italic),
)
@Immutable
class TangemTypography internal constructor(
fontFamily: FontFamily,

View file

@ -0,0 +1,348 @@
package com.tangem.core.ui.res
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.LineHeightStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.tangem.core.ui.R
internal val InterFamily = FontFamily(
Font(R.font.inter_regular),
Font(R.font.inter_italic, style = FontStyle.Italic),
)
@Stable
class TangemTypography2 internal constructor(
fontFamily: FontFamily,
) {
val titleRegular44: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 44.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = 0.37f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 48f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingRegular34: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 34.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = 0.37f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 40f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingBold34: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 34.sp,
fontWeight = FontWeight.Bold,
letterSpacing = TextUnit(value = 0.37f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 40f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingRegular28: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 28.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = 0.36f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 36f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingBold28: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 28.sp,
fontWeight = FontWeight.Bold,
letterSpacing = TextUnit(value = 0.36f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 36f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingRegular22: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 22.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = 0.35f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 28f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingBold22: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 22.sp,
fontWeight = FontWeight.Bold,
letterSpacing = TextUnit(value = 0.35f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 28f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingRegular20: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 20.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = 0.38f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 24f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingSemibold20: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 20.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = 0.38f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 24f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingRegular17: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 17.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = -0.41f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 20f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val headingSemibold17: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 17.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = -0.2f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 20f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val bodyRegular16: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 16.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = -0.32f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 20f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val bodySemibold16: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 16.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = -0.32f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 20f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val bodyRegular15: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 15.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = -0.24f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 20f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val bodySemibold15: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 15.sp,
fontWeight = FontWeight.Medium,
letterSpacing = TextUnit(value = -0.1f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 20f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val bodyRegular14: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
letterSpacing = TextUnit(value = -0.1f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 16f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val captionRegular13: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 13.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = -0.08f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 16f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val captionSemibold13: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 13.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = 0.1f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 16f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val captionRegular12: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 12.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = 0f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 16f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val captionSemibold12: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
letterSpacing = TextUnit(value = 0.1f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 16f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val captionRegular11: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 11.sp,
fontWeight = FontWeight.Normal,
letterSpacing = TextUnit(value = 0.07f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 12f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
val captionSemibold11: TextStyle = TextStyle(
fontFamily = fontFamily,
fontSize = 11.sp,
fontWeight = FontWeight.SemiBold,
letterSpacing = TextUnit(value = 0.15f, type = TextUnitType.Sp),
lineHeight = TextUnit(value = 12f, type = TextUnitType.Sp),
lineHeightStyle = LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None,
),
)
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 360, heightDp = 1500)
@Preview(showBackground = true, widthDp = 360, heightDp = 1500, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun TangemTypography2_Preview() {
TangemThemePreviewRedesign {
val typographyList = sequenceOf(
TangemTheme.typography2.titleRegular44,
TangemTheme.typography2.headingRegular34,
TangemTheme.typography2.headingBold34,
TangemTheme.typography2.headingRegular28,
TangemTheme.typography2.headingBold28,
TangemTheme.typography2.headingRegular22,
TangemTheme.typography2.headingBold22,
TangemTheme.typography2.headingRegular20,
TangemTheme.typography2.headingSemibold20,
TangemTheme.typography2.headingRegular17,
TangemTheme.typography2.headingSemibold17,
TangemTheme.typography2.bodyRegular16,
TangemTheme.typography2.bodySemibold16,
TangemTheme.typography2.bodyRegular15,
TangemTheme.typography2.bodySemibold15,
TangemTheme.typography2.bodyRegular14,
TangemTheme.typography2.captionRegular13,
TangemTheme.typography2.captionSemibold13,
TangemTheme.typography2.captionRegular12,
TangemTheme.typography2.captionSemibold12,
TangemTheme.typography2.captionRegular11,
TangemTheme.typography2.captionSemibold11,
)
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.background(TangemTheme.colors2.surface.level1)
.padding(4.dp),
) {
typographyList.forEach { textStyle ->
Box(modifier = Modifier.heightIn(min = 60.dp)) {
Text(
text = "Lorem ipsum",
style = textStyle,
color = TangemTheme.colors2.text.neutral.primary,
modifier = Modifier.align(Alignment.Center),
)
}
}
}
}
}
// endregion

@ -1 +1 @@
Subproject commit d7950d60bb4c6353f2aa3364073c6ec72167c666
Subproject commit fa10299aec0b3a06fda9bf6d050e0aa79609d33b