diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt b/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt index 5ca9a16de8..11682ec1f1 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/Buttons.kt @@ -2,19 +2,17 @@ package com.tangem.core.ui.components import androidx.annotation.DrawableRes import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.material.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.TextStyle import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp import com.tangem.core.ui.R +import com.tangem.core.ui.components.buttons.common.TangemButton +import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition +import com.tangem.core.ui.components.buttons.common.TangemButtonSize +import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults import com.tangem.core.ui.res.TangemTheme // region TextButton @@ -26,7 +24,7 @@ fun TextButton(text: String, onClick: () -> Unit, modifier: Modifier = Modifier, TangemButton( modifier = modifier, text = text, - icon = TangemButtonIcon.None, + icon = TangemButtonIconPosition.None, onClick = onClick, enabled = enabled, showProgress = false, @@ -49,7 +47,7 @@ fun TextButtonIconStart( TangemButton( modifier = modifier, text = text, - icon = TangemButtonIcon.Start(iconResId), + icon = TangemButtonIconPosition.Start(iconResId), onClick = onClick, enabled = enabled, showProgress = false, @@ -63,7 +61,7 @@ fun WarningTextButton(text: String, onClick: () -> Unit, modifier: Modifier = Mo TangemButton( modifier = modifier, text = text, - icon = TangemButtonIcon.None, + icon = TangemButtonIconPosition.None, onClick = onClick, enabled = enabled, showProgress = false, @@ -85,7 +83,7 @@ fun PrimaryButton( TangemButton( modifier = modifier, text = text, - icon = TangemButtonIcon.None, + icon = TangemButtonIconPosition.None, onClick = onClick, colors = TangemButtonsDefaults.primaryButtonColors, enabled = enabled, @@ -108,7 +106,7 @@ fun PrimaryButtonIconEnd( TangemButton( modifier = modifier, text = text, - icon = TangemButtonIcon.End(iconResId), + icon = TangemButtonIconPosition.End(iconResId), onClick = onClick, colors = TangemButtonsDefaults.primaryButtonColors, enabled = enabled, @@ -131,7 +129,7 @@ fun PrimaryButtonIconStart( TangemButton( modifier = modifier, text = text, - icon = TangemButtonIcon.Start(iconResId), + icon = TangemButtonIconPosition.Start(iconResId), onClick = onClick, colors = TangemButtonsDefaults.primaryButtonColors, enabled = enabled, @@ -152,7 +150,7 @@ fun SecondaryButton( TangemButton( modifier = modifier, text = text, - icon = TangemButtonIcon.None, + icon = TangemButtonIconPosition.None, onClick = onClick, colors = TangemButtonsDefaults.secondaryButtonColors, enabled = enabled, @@ -175,7 +173,7 @@ fun SecondaryButtonIconEnd( TangemButton( modifier = modifier, text = text, - icon = TangemButtonIcon.End(iconResId), + icon = TangemButtonIconPosition.End(iconResId), onClick = onClick, colors = TangemButtonsDefaults.secondaryButtonColors, enabled = enabled, @@ -198,7 +196,7 @@ fun SecondaryButtonIconStart( TangemButton( modifier = modifier, text = text, - icon = TangemButtonIcon.Start(iconResId), + icon = TangemButtonIconPosition.Start(iconResId), onClick = onClick, colors = TangemButtonsDefaults.secondaryButtonColors, enabled = enabled, @@ -214,7 +212,7 @@ fun SelectorButton(text: String, onClick: () -> Unit, modifier: Modifier = Modif modifier = modifier, text = text, textStyle = TangemTheme.typography.subtitle2, - icon = TangemButtonIcon.End(iconResId = R.drawable.ic_chevron_24), + icon = TangemButtonIconPosition.End(iconResId = R.drawable.ic_chevron_24), onClick = onClick, colors = TangemButtonsDefaults.selectorButtonColors, showProgress = false, @@ -224,362 +222,6 @@ fun SelectorButton(text: String, onClick: () -> Unit, modifier: Modifier = Modif } // endregion Other -// region Action - -/** - * [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=290-305&t=3z98eFnTeyIx5TH5-4) - * */ -@Composable -fun RoundedActionButton( - text: String, - @DrawableRes iconResId: Int, - onClick: () -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, -) { - TangemButton( - modifier = modifier, - text = text, - icon = TangemButtonIcon.Start(iconResId), - onClick = onClick, - enabled = enabled, - showProgress = false, - colors = TangemButtonsDefaults.secondaryButtonColors, - size = TangemButtonSize.RoundedAction, - ) -} - -/** - * [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=1208-1395&t=3z98eFnTeyIx5TH5-4) - * */ -@Composable -fun ActionButton( - text: String, - @DrawableRes iconResId: Int, - onClick: () -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, -) { - TangemButton( - modifier = modifier, - text = text, - icon = TangemButtonIcon.Start(iconResId), - onClick = onClick, - enabled = enabled, - showProgress = false, - colors = TangemButtonsDefaults.secondaryButtonColors, - size = TangemButtonSize.Action, - ) -} - -/** - * Same as [RoundedActionButton] but colored in primary background color - * */ -@Composable -fun BackgroundActionButton( - text: String, - @DrawableRes iconResId: Int, - onClick: () -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, -) { - TangemButton( - modifier = modifier, - text = text, - icon = TangemButtonIcon.Start(iconResId), - onClick = onClick, - enabled = enabled, - showProgress = false, - colors = TangemButtonsDefaults.backgroundButtonColors, - size = TangemButtonSize.RoundedAction, - ) -} -// endregion Action - -// region Defaults -@Suppress("LongParameterList") -@Composable -private fun TangemButton( - text: String, - icon: TangemButtonIcon, - onClick: () -> Unit, - colors: ButtonColors, - showProgress: Boolean, - enabled: Boolean, - modifier: Modifier = Modifier, - size: TangemButtonSize = TangemButtonSize.Default, - elevation: ButtonElevation = TangemButtonsDefaults.elevation, - textStyle: TextStyle = TangemTheme.typography.button, -) { - Button( - modifier = modifier.heightIn(min = size.toHeightDp()), - onClick = { if (!showProgress) onClick() }, - enabled = enabled, - elevation = elevation, - shape = size.toShape(), - colors = colors, - contentPadding = size.toContentPadding(icon = icon), - ) { - ButtonContent( - text = text, - textStyle = textStyle, - buttonIcon = icon, - colors = colors, - showProgress = showProgress, - enabled = enabled, - size = size, - ) - } -} - -@Suppress("LongParameterList") -@Composable -private fun ButtonContent( - text: String, - textStyle: TextStyle, - buttonIcon: TangemButtonIcon, - colors: ButtonColors, - size: TangemButtonSize, - enabled: Boolean, - showProgress: Boolean, -) { - val icon = @Composable { iconResId: Int -> - Icon( - modifier = Modifier.size(TangemTheme.dimens.size20), - painter = painterResource(id = iconResId), - tint = colors.contentColor(enabled = enabled).value, - contentDescription = null, - ) - } - - if (showProgress) { - Box(modifier = Modifier.wrapContentSize()) { - CircularProgressIndicator( - modifier = Modifier - .align(Alignment.Center) - .size(TangemTheme.dimens.size24), - color = colors.contentColor(enabled = enabled).value, - strokeWidth = TangemTheme.dimens.size4, - ) - } - } else { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(size.toIconPadding()), - ) { - if (buttonIcon is TangemButtonIcon.Start) { - icon(buttonIcon.iconResId) - } - Text( - text = text, - style = textStyle, - color = colors.contentColor(enabled = enabled).value, - maxLines = 1, - ) - if (buttonIcon is TangemButtonIcon.End) { - icon(buttonIcon.iconResId) - } - } - } -} - -@Immutable -private sealed interface TangemButtonIcon { - val iconResId: Int? - - data class Start(override val iconResId: Int) : TangemButtonIcon - - data class End(override val iconResId: Int) : TangemButtonIcon - - object None : TangemButtonIcon { - override val iconResId: Int? = null - } -} - -private enum class TangemButtonSize { - Default, - Text, - Selector, - Action, - RoundedAction, -} - -@Composable -@ReadOnlyComposable -private fun TangemButtonSize.toHeightDp(): Dp = when (this) { - TangemButtonSize.Default -> TangemTheme.dimens.size48 - TangemButtonSize.Text -> TangemTheme.dimens.size40 - TangemButtonSize.Selector -> TangemTheme.dimens.size24 - TangemButtonSize.Action, - TangemButtonSize.RoundedAction, - -> TangemTheme.dimens.size36 -} - -@Composable -@ReadOnlyComposable -private fun TangemButtonSize.toShape(): Shape = when (this) { - TangemButtonSize.Default -> TangemTheme.shapes.roundedCornersMedium - TangemButtonSize.Text -> TangemTheme.shapes.roundedCornersSmall - TangemButtonSize.Selector -> TangemTheme.shapes.roundedCornersSmall - TangemButtonSize.Action -> TangemTheme.shapes.roundedCornersMedium - TangemButtonSize.RoundedAction -> TangemTheme.shapes.roundedCornersLarge -} - -@Composable -@ReadOnlyComposable -private fun TangemButtonSize.toIconPadding(): Dp = when (this) { - TangemButtonSize.Default -> TangemTheme.dimens.spacing8 - TangemButtonSize.Text -> TangemTheme.dimens.spacing8 - TangemButtonSize.Selector -> 0.dp - TangemButtonSize.Action, - TangemButtonSize.RoundedAction, - -> TangemTheme.dimens.spacing8 -} - -@Composable -@ReadOnlyComposable -private fun TangemButtonSize.toContentPadding(icon: TangemButtonIcon): PaddingValues { - val horizontalPadding = this.toHorizontalContentPadding(icon = icon) - - return when (this) { - TangemButtonSize.Default -> PaddingValues( - top = TangemTheme.dimens.spacing14, - bottom = TangemTheme.dimens.spacing14, - start = horizontalPadding.first, - end = horizontalPadding.second, - ) - TangemButtonSize.Text -> PaddingValues( - top = TangemTheme.dimens.spacing10, - bottom = TangemTheme.dimens.spacing10, - start = horizontalPadding.first, - end = horizontalPadding.second, - ) - TangemButtonSize.Selector -> PaddingValues( - top = TangemTheme.dimens.spacing0_5, - bottom = TangemTheme.dimens.spacing0_5, - start = horizontalPadding.first, - end = horizontalPadding.second, - ) - TangemButtonSize.Action, - TangemButtonSize.RoundedAction, - -> PaddingValues( - top = TangemTheme.dimens.spacing8, - bottom = TangemTheme.dimens.spacing8, - start = horizontalPadding.first, - end = horizontalPadding.second, - ) - } -} - -@Composable -@ReadOnlyComposable -private fun TangemButtonSize.toHorizontalContentPadding(icon: TangemButtonIcon): Pair { - return when (this) { - TangemButtonSize.Default -> TangemTheme.dimens.spacing32 to TangemTheme.dimens.spacing32 - TangemButtonSize.Text -> when (icon) { - is TangemButtonIcon.None -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing16 - is TangemButtonIcon.Start -> TangemTheme.dimens.spacing14 to TangemTheme.dimens.spacing16 - is TangemButtonIcon.End -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing14 - } - TangemButtonSize.Selector -> TangemTheme.dimens.spacing0_5 to TangemTheme.dimens.spacing0_5 - TangemButtonSize.Action, - TangemButtonSize.RoundedAction, - -> when (icon) { - is TangemButtonIcon.None -> TangemTheme.dimens.spacing24 to TangemTheme.dimens.spacing24 - is TangemButtonIcon.Start -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing24 - is TangemButtonIcon.End -> TangemTheme.dimens.spacing24 to TangemTheme.dimens.spacing16 - } - } -} - -private object TangemButtonsDefaults { - val elevation: ButtonElevation - @Composable get() = ButtonDefaults - .elevation( - defaultElevation = TangemTheme.dimens.elevation0, - pressedElevation = TangemTheme.dimens.elevation0, - ) - - val primaryButtonColors: ButtonColors - @Composable - @ReadOnlyComposable - get() = TangemButtonColors( - backgroundColor = TangemTheme.colors.button.primary, - contentColor = TangemTheme.colors.text.primary2, - disabledBackgroundColor = TangemTheme.colors.button.disabled, - disabledContentColor = TangemTheme.colors.text.disabled, - ) - - val secondaryButtonColors: ButtonColors - @Composable - @ReadOnlyComposable - get() = TangemButtonColors( - backgroundColor = TangemTheme.colors.button.secondary, - contentColor = TangemTheme.colors.text.primary1, - disabledBackgroundColor = TangemTheme.colors.button.disabled, - disabledContentColor = TangemTheme.colors.text.disabled, - ) - - val defaultTextButtonColors: ButtonColors - @Composable - @ReadOnlyComposable - get() = TangemButtonColors( - backgroundColor = Color.Transparent, - contentColor = TangemTheme.colors.text.secondary, - disabledBackgroundColor = Color.Transparent, - disabledContentColor = TangemTheme.colors.text.disabled, - ) - - val warningTextButtonColors: ButtonColors - @Composable - @ReadOnlyComposable - get() = TangemButtonColors( - backgroundColor = Color.Transparent, - contentColor = TangemTheme.colors.text.warning, - disabledBackgroundColor = Color.Transparent, - disabledContentColor = TangemTheme.colors.text.disabled, - ) - - val selectorButtonColors: ButtonColors - @Composable - @ReadOnlyComposable - get() = TangemButtonColors( - backgroundColor = Color.Transparent, - contentColor = TangemTheme.colors.text.tertiary, - disabledBackgroundColor = Color.Transparent, - disabledContentColor = TangemTheme.colors.text.disabled, - ) - - val backgroundButtonColors: ButtonColors - @Composable - @ReadOnlyComposable - get() = TangemButtonColors( - backgroundColor = TangemTheme.colors.background.primary, - contentColor = TangemTheme.colors.text.primary1, - disabledBackgroundColor = TangemTheme.colors.button.disabled, - disabledContentColor = TangemTheme.colors.text.disabled, - ) -} - -@Immutable -private open class TangemButtonColors( - private val backgroundColor: Color, - private val contentColor: Color, - private val disabledBackgroundColor: Color, - private val disabledContentColor: Color, -) : ButtonColors { - @Composable - override fun backgroundColor(enabled: Boolean): State { - return rememberUpdatedState(newValue = if (enabled) backgroundColor else disabledBackgroundColor) - } - - @Composable - override fun contentColor(enabled: Boolean): State { - return rememberUpdatedState(newValue = if (enabled) contentColor else disabledContentColor) - } -} -// endregion Defaults - // region Preview @Composable private fun PrimaryButtonSample() { @@ -730,34 +372,4 @@ private fun TextButtonPreview_DarkTheme() { } } -@Composable -private fun ActionButtonSample() { - Column( - modifier = Modifier.background(TangemTheme.colors.background.primary), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8), - ) { - RoundedActionButton(text = "Send", iconResId = R.drawable.ic_arrow_up_24, onClick = { }) - ActionButton(text = "Send", iconResId = R.drawable.ic_arrow_up_24, onClick = { }) - BackgroundActionButton(text = "Send", iconResId = R.drawable.ic_arrow_up_24, onClick = { }) - RoundedActionButton(text = "Send", iconResId = R.drawable.ic_arrow_up_24, enabled = false, onClick = { }) - ActionButton(text = "Send", iconResId = R.drawable.ic_arrow_up_24, enabled = false, onClick = { }) - BackgroundActionButton(text = "Send", iconResId = R.drawable.ic_arrow_up_24, enabled = false, onClick = { }) - } -} - -@Preview(showBackground = true, widthDp = 360) -@Composable -private fun ActionButtonPreview_LightTheme() { - TangemTheme { - ActionButtonSample() - } -} - -@Preview(showBackground = true, widthDp = 360) -@Composable -private fun ActionButtonPreview_DarkTheme() { - TangemTheme(isDark = true) { - ActionButtonSample() - } -} // endregion Preview \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/ActionConfig.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/ActionConfig.kt new file mode 100644 index 0000000000..dbfc71c767 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/ActionConfig.kt @@ -0,0 +1,20 @@ +package com.tangem.core.ui.components.buttons.actions + +import androidx.annotation.DrawableRes + +/** + * Action button config + * + * @property text text + * @property iconResId icon resource id + * @property onClick lambda be invoked when action component is clicked + * @property enabled enabled + * +[REDACTED_AUTHOR] + */ +data class ActionConfig( + val text: String, + @DrawableRes val iconResId: Int, + val onClick: () -> Unit, + val enabled: Boolean = true, +) \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt new file mode 100644 index 0000000000..e755e7c8b9 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/actions/Actions.kt @@ -0,0 +1,96 @@ +package com.tangem.core.ui.components.buttons.actions + +import androidx.compose.foundation.layout.Column +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.datasource.CollectionPreviewParameterProvider +import com.tangem.core.ui.R +import com.tangem.core.ui.components.buttons.common.TangemButton +import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition +import com.tangem.core.ui.components.buttons.common.TangemButtonSize +import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults +import com.tangem.core.ui.res.TangemTheme + +/** + * [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=290-305&t=3z98eFnTeyIx5TH5-4) + */ +@Composable +fun RoundedActionButton(config: ActionConfig, modifier: Modifier = Modifier) { + TangemButton( + modifier = modifier, + text = config.text, + icon = TangemButtonIconPosition.Start(config.iconResId), + onClick = config.onClick, + enabled = config.enabled, + showProgress = false, + colors = TangemButtonsDefaults.secondaryButtonColors, + size = TangemButtonSize.RoundedAction, + ) +} + +/** + * [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=1208-1395&t=3z98eFnTeyIx5TH5-4) + */ +@Composable +fun ActionButton(config: ActionConfig, modifier: Modifier = Modifier) { + TangemButton( + modifier = modifier, + text = config.text, + icon = TangemButtonIconPosition.Start(config.iconResId), + onClick = config.onClick, + enabled = config.enabled, + showProgress = false, + colors = TangemButtonsDefaults.secondaryButtonColors, + size = TangemButtonSize.Action, + ) +} + +/** + * Same as [RoundedActionButton] but colored in primary background color + */ +@Composable +fun BackgroundActionButton(config: ActionConfig, modifier: Modifier = Modifier) { + TangemButton( + modifier = modifier, + text = config.text, + icon = TangemButtonIconPosition.Start(config.iconResId), + onClick = config.onClick, + enabled = config.enabled, + showProgress = false, + colors = TangemButtonsDefaults.backgroundButtonColors, + size = TangemButtonSize.RoundedAction, + ) +} + +@Preview(showBackground = true) +@Composable +private fun Preview_ActionButton_Light(@PreviewParameter(ActionStateProvider::class) state: ActionConfig) { + TangemTheme(isDark = false) { + Column { + RoundedActionButton(state) + ActionButton(state) + BackgroundActionButton(state) + } + } +} + +@Preview(showBackground = true) +@Composable +private fun Preview_ActionButton_Dark(@PreviewParameter(ActionStateProvider::class) state: ActionConfig) { + TangemTheme { + Column { + RoundedActionButton(state) + ActionButton(state) + BackgroundActionButton(state) + } + } +} + +private class ActionStateProvider : CollectionPreviewParameterProvider( + collection = listOf( + ActionConfig(text = "Send", iconResId = R.drawable.ic_arrow_up_24, onClick = {}), + ActionConfig(text = "Receive", iconResId = R.drawable.ic_arrow_down_24, enabled = false, onClick = {}), + ), +) \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButton.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButton.kt new file mode 100644 index 0000000000..b0a5b59116 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButton.kt @@ -0,0 +1,96 @@ +package com.tangem.core.ui.components.buttons.common + +import androidx.compose.foundation.layout.* +import androidx.compose.material.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.TextStyle +import com.tangem.core.ui.res.TangemTheme + +@Suppress("LongParameterList") +@Composable +internal fun TangemButton( + text: String, + icon: TangemButtonIconPosition, + onClick: () -> Unit, + colors: ButtonColors, + showProgress: Boolean, + enabled: Boolean, + modifier: Modifier = Modifier, + size: TangemButtonSize = TangemButtonSize.Default, + elevation: ButtonElevation = TangemButtonsDefaults.elevation, + textStyle: TextStyle = TangemTheme.typography.button, +) { + Button( + modifier = modifier.heightIn(min = size.toHeightDp()), + onClick = { if (!showProgress) onClick() }, + enabled = enabled, + elevation = elevation, + shape = size.toShape(), + colors = colors, + contentPadding = size.toContentPadding(icon = icon), + ) { + ButtonContent( + text = text, + textStyle = textStyle, + buttonIcon = icon, + colors = colors, + showProgress = showProgress, + enabled = enabled, + size = size, + ) + } +} + +@Suppress("LongParameterList") +@Composable +private fun ButtonContent( + text: String, + textStyle: TextStyle, + buttonIcon: TangemButtonIconPosition, + colors: ButtonColors, + size: TangemButtonSize, + enabled: Boolean, + showProgress: Boolean, +) { + val icon = @Composable { iconResId: Int -> + Icon( + modifier = Modifier.size(TangemTheme.dimens.size20), + painter = painterResource(id = iconResId), + tint = colors.contentColor(enabled = enabled).value, + contentDescription = null, + ) + } + + if (showProgress) { + Box(modifier = Modifier.wrapContentSize()) { + CircularProgressIndicator( + modifier = Modifier + .align(Alignment.Center) + .size(TangemTheme.dimens.size24), + color = colors.contentColor(enabled = enabled).value, + strokeWidth = TangemTheme.dimens.size4, + ) + } + } else { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(size.toIconPadding()), + ) { + if (buttonIcon is TangemButtonIconPosition.Start) { + icon(buttonIcon.iconResId) + } + Text( + text = text, + style = textStyle, + color = colors.contentColor(enabled = enabled).value, + maxLines = 1, + ) + if (buttonIcon is TangemButtonIconPosition.End) { + icon(buttonIcon.iconResId) + } + } + } +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonColors.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonColors.kt new file mode 100644 index 0000000000..92a334a139 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonColors.kt @@ -0,0 +1,25 @@ +package com.tangem.core.ui.components.buttons.common + +import androidx.compose.material.ButtonColors +import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.ui.graphics.Color + +internal class TangemButtonColors( + private val backgroundColor: Color, + private val contentColor: Color, + private val disabledBackgroundColor: Color, + private val disabledContentColor: Color, +) : ButtonColors { + + @Composable + override fun backgroundColor(enabled: Boolean): State { + return rememberUpdatedState(newValue = if (enabled) backgroundColor else disabledBackgroundColor) + } + + @Composable + override fun contentColor(enabled: Boolean): State { + return rememberUpdatedState(newValue = if (enabled) contentColor else disabledContentColor) + } +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonIconPosition.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonIconPosition.kt new file mode 100644 index 0000000000..0896e671fb --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonIconPosition.kt @@ -0,0 +1,16 @@ +package com.tangem.core.ui.components.buttons.common + +import androidx.annotation.DrawableRes + +internal sealed interface TangemButtonIconPosition { + val iconResId: Int? + + data class Start(@DrawableRes override val iconResId: Int) : TangemButtonIconPosition + + data class End(@DrawableRes override val iconResId: Int) : TangemButtonIconPosition + + object None : TangemButtonIconPosition { + @DrawableRes + override val iconResId: Int? = null + } +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonSize.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonSize.kt new file mode 100644 index 0000000000..6ba9b10d72 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonSize.kt @@ -0,0 +1,105 @@ +package com.tangem.core.ui.components.buttons.common + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.tangem.core.ui.res.TangemTheme + +internal enum class TangemButtonSize { + Default, + Text, + Selector, + Action, + RoundedAction, +} + +@Composable +@ReadOnlyComposable +internal fun TangemButtonSize.toHeightDp(): Dp = when (this) { + TangemButtonSize.Default -> TangemTheme.dimens.size48 + TangemButtonSize.Text -> TangemTheme.dimens.size40 + TangemButtonSize.Selector -> TangemTheme.dimens.size24 + TangemButtonSize.Action, + TangemButtonSize.RoundedAction, + -> TangemTheme.dimens.size36 +} + +@Composable +@ReadOnlyComposable +internal fun TangemButtonSize.toShape(): Shape = when (this) { + TangemButtonSize.Default -> TangemTheme.shapes.roundedCornersMedium + TangemButtonSize.Text -> TangemTheme.shapes.roundedCornersSmall + TangemButtonSize.Selector -> TangemTheme.shapes.roundedCornersSmall + TangemButtonSize.Action -> TangemTheme.shapes.roundedCornersMedium + TangemButtonSize.RoundedAction -> TangemTheme.shapes.roundedCornersLarge +} + +@Composable +@ReadOnlyComposable +internal fun TangemButtonSize.toIconPadding(): Dp = when (this) { + TangemButtonSize.Default -> TangemTheme.dimens.spacing8 + TangemButtonSize.Text -> TangemTheme.dimens.spacing8 + TangemButtonSize.Selector -> 0.dp + TangemButtonSize.Action, + TangemButtonSize.RoundedAction, + -> TangemTheme.dimens.spacing8 +} + +@Composable +@ReadOnlyComposable +internal fun TangemButtonSize.toContentPadding(icon: TangemButtonIconPosition): PaddingValues { + val horizontalPadding = this.toHorizontalContentPadding(icon = icon) + + return when (this) { + TangemButtonSize.Default -> PaddingValues( + top = TangemTheme.dimens.spacing14, + bottom = TangemTheme.dimens.spacing14, + start = horizontalPadding.first, + end = horizontalPadding.second, + ) + TangemButtonSize.Text -> PaddingValues( + top = TangemTheme.dimens.spacing10, + bottom = TangemTheme.dimens.spacing10, + start = horizontalPadding.first, + end = horizontalPadding.second, + ) + TangemButtonSize.Selector -> PaddingValues( + top = TangemTheme.dimens.spacing0_5, + bottom = TangemTheme.dimens.spacing0_5, + start = horizontalPadding.first, + end = horizontalPadding.second, + ) + TangemButtonSize.Action, + TangemButtonSize.RoundedAction, + -> PaddingValues( + top = TangemTheme.dimens.spacing8, + bottom = TangemTheme.dimens.spacing8, + start = horizontalPadding.first, + end = horizontalPadding.second, + ) + } +} + +@Composable +@ReadOnlyComposable +internal fun TangemButtonSize.toHorizontalContentPadding(icon: TangemButtonIconPosition): Pair { + return when (this) { + TangemButtonSize.Default -> TangemTheme.dimens.spacing32 to TangemTheme.dimens.spacing32 + TangemButtonSize.Text -> when (icon) { + is TangemButtonIconPosition.None -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing16 + is TangemButtonIconPosition.Start -> TangemTheme.dimens.spacing14 to TangemTheme.dimens.spacing16 + is TangemButtonIconPosition.End -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing14 + } + TangemButtonSize.Selector -> TangemTheme.dimens.spacing0_5 to TangemTheme.dimens.spacing0_5 + TangemButtonSize.Action, + TangemButtonSize.RoundedAction, + -> when (icon) { + is TangemButtonIconPosition.None -> TangemTheme.dimens.spacing24 to TangemTheme.dimens.spacing24 + is TangemButtonIconPosition.Start -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing24 + is TangemButtonIconPosition.End -> TangemTheme.dimens.spacing24 to TangemTheme.dimens.spacing16 + } + } +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonsDefaults.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonsDefaults.kt new file mode 100644 index 0000000000..f6c6211dc5 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/common/TangemButtonsDefaults.kt @@ -0,0 +1,78 @@ +package com.tangem.core.ui.components.buttons.common + +import androidx.compose.material.ButtonColors +import androidx.compose.material.ButtonDefaults +import androidx.compose.material.ButtonElevation +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.ui.graphics.Color +import com.tangem.core.ui.res.TangemTheme + +internal object TangemButtonsDefaults { + + val elevation: ButtonElevation + @Composable get() = ButtonDefaults.elevation( + defaultElevation = TangemTheme.dimens.elevation0, + pressedElevation = TangemTheme.dimens.elevation0, + ) + + val primaryButtonColors: ButtonColors + @Composable + @ReadOnlyComposable + get() = TangemButtonColors( + backgroundColor = TangemTheme.colors.button.primary, + contentColor = TangemTheme.colors.text.primary2, + disabledBackgroundColor = TangemTheme.colors.button.disabled, + disabledContentColor = TangemTheme.colors.text.disabled, + ) + + val secondaryButtonColors: ButtonColors + @Composable + @ReadOnlyComposable + get() = TangemButtonColors( + backgroundColor = TangemTheme.colors.button.secondary, + contentColor = TangemTheme.colors.text.primary1, + disabledBackgroundColor = TangemTheme.colors.button.disabled, + disabledContentColor = TangemTheme.colors.text.disabled, + ) + + val defaultTextButtonColors: ButtonColors + @Composable + @ReadOnlyComposable + get() = TangemButtonColors( + backgroundColor = Color.Transparent, + contentColor = TangemTheme.colors.text.secondary, + disabledBackgroundColor = Color.Transparent, + disabledContentColor = TangemTheme.colors.text.disabled, + ) + + val warningTextButtonColors: ButtonColors + @Composable + @ReadOnlyComposable + get() = TangemButtonColors( + backgroundColor = Color.Transparent, + contentColor = TangemTheme.colors.text.warning, + disabledBackgroundColor = Color.Transparent, + disabledContentColor = TangemTheme.colors.text.disabled, + ) + + val selectorButtonColors: ButtonColors + @Composable + @ReadOnlyComposable + get() = TangemButtonColors( + backgroundColor = Color.Transparent, + contentColor = TangemTheme.colors.text.tertiary, + disabledBackgroundColor = Color.Transparent, + disabledContentColor = TangemTheme.colors.text.disabled, + ) + + val backgroundButtonColors: ButtonColors + @Composable + @ReadOnlyComposable + get() = TangemButtonColors( + backgroundColor = TangemTheme.colors.background.primary, + contentColor = TangemTheme.colors.text.primary1, + disabledBackgroundColor = TangemTheme.colors.button.disabled, + disabledContentColor = TangemTheme.colors.text.disabled, + ) +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt index 5fcea3bc6c..d64e296c88 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt @@ -170,6 +170,14 @@ internal object WalletPreviewData { ), ) + val manageButtons = persistentListOf( + WalletManageButton.Buy(onClick = {}), + WalletManageButton.Send(onClick = {}), + WalletManageButton.Receive(onClick = {}), + WalletManageButton.Exchange(onClick = {}), + WalletManageButton.CopyAddress(onClick = {}), + ) + val multicurrencyWalletScreenState = WalletStateHolder.MultiCurrencyContent( onBackClick = {}, topBarConfig = walletTopBarConfig, @@ -273,5 +281,6 @@ internal object WalletPreviewData { WalletNotification.NeedToBackup(onClick = {}), WalletNotification.ScanCard(onClick = {}), ), + buttons = manageButtons, ) } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensScreen.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensScreen.kt index 4f3cda259d..685d1ab9f5 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensScreen.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/organizetokens/OrganizeTokensScreen.kt @@ -21,9 +21,10 @@ 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.datasource.CollectionPreviewParameterProvider -import com.tangem.core.ui.components.BackgroundActionButton import com.tangem.core.ui.components.PrimaryButton import com.tangem.core.ui.components.SecondaryButton +import com.tangem.core.ui.components.buttons.actions.ActionConfig +import com.tangem.core.ui.components.buttons.actions.BackgroundActionButton import com.tangem.core.ui.res.TangemTheme import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.presentation.common.WalletPreviewData @@ -214,16 +215,20 @@ private fun TopBar( horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8), ) { BackgroundActionButton( + config = ActionConfig( + text = stringResource(id = R.string.organize_tokens_sort_by_balance), + iconResId = R.drawable.ic_sort_24, + onClick = config.onSortByBalanceClick, + ), modifier = Modifier.weight(1f), - text = stringResource(id = R.string.organize_tokens_sort_by_balance), - iconResId = R.drawable.ic_sort_24, - onClick = config.onSortByBalanceClick, ) BackgroundActionButton( + config = ActionConfig( + text = stringResource(id = R.string.organize_tokens_group), + iconResId = R.drawable.ic_group_24, + onClick = config.onGroupByNetworkClick, + ), modifier = Modifier.weight(1f), - text = stringResource(id = R.string.organize_tokens_group), - iconResId = R.drawable.ic_group_24, - onClick = config.onGroupByNetworkClick, ) } } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButton.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButton.kt new file mode 100644 index 0000000000..c4e41ed1b6 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButton.kt @@ -0,0 +1,79 @@ +package com.tangem.feature.wallet.presentation.wallet.state + +import com.tangem.core.ui.components.buttons.actions.ActionConfig +import com.tangem.feature.wallet.impl.R + +/** + * Wallet manage button state + * + * @param config action config + * +[REDACTED_AUTHOR] + */ +sealed class WalletManageButton(val config: ActionConfig) { + + /** + * Buy + * + * @param onClick lambda be invoked when manage button is clicked + */ + data class Buy(val onClick: () -> Unit) : WalletManageButton( + config = ActionConfig( + text = "Buy", + iconResId = R.drawable.ic_plus_24, + onClick = onClick, + ), + ) + + /** + * Send + * + * @param onClick lambda be invoked when manage button is clicked + */ + data class Send(val onClick: () -> Unit) : WalletManageButton( + config = ActionConfig( + text = "Send", + iconResId = R.drawable.ic_arrow_up_24, + onClick = onClick, + ), + ) + + /** + * Receive + * + * @param onClick lambda be invoked when manage button is clicked + */ + data class Receive(val onClick: () -> Unit) : WalletManageButton( + config = ActionConfig( + text = "Receive", + iconResId = R.drawable.ic_arrow_down_24, + onClick = onClick, + ), + ) + + /** + * Exchange + * + * @param onClick lambda be invoked when manage button is clicked + */ + data class Exchange(val onClick: () -> Unit) : WalletManageButton( + config = ActionConfig( + text = "Exchange", + iconResId = R.drawable.ic_exchange_vertical_24, + onClick = onClick, + ), + ) + + /** + * Copy address + * + * @param onClick lambda be invoked when manage button is clicked + */ + data class CopyAddress(val onClick: () -> Unit) : WalletManageButton( + config = ActionConfig( + text = "Copy address", + iconResId = R.drawable.ic_copy_24, + onClick = onClick, + ), + ) +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButtons.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButtons.kt new file mode 100644 index 0000000000..966ff09e16 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletManageButtons.kt @@ -0,0 +1,64 @@ +package com.tangem.feature.wallet.presentation.wallet.state + +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.rememberScrollState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.key +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.datasource.CollectionPreviewParameterProvider +import com.tangem.core.ui.components.buttons.actions.ActionButton +import com.tangem.core.ui.res.TangemTheme +import com.tangem.feature.wallet.presentation.common.WalletPreviewData +import kotlinx.collections.immutable.ImmutableList + +/** + * Wallet manage buttons + * + * @param buttons manage buttons + * +[REDACTED_AUTHOR] + */ +@Composable +internal fun WalletManageButtons(buttons: ImmutableList) { + Row( + modifier = Modifier + .horizontalScroll(state = rememberScrollState()) + .fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing8), + ) { + buttons.forEach { button -> + key(button.config.text) { + ActionButton(config = button.config) + } + } + } +} + +@Preview +@Composable +private fun Preview_WalletManageButtons_Light( + @PreviewParameter(WalletManageButtonProvider::class) buttons: ImmutableList, +) { + TangemTheme(isDark = false) { + WalletManageButtons(buttons = buttons) + } +} + +@Preview +@Composable +private fun Preview_WalletManageButtons_Dark( + @PreviewParameter(WalletManageButtonProvider::class) buttons: ImmutableList, +) { + TangemTheme(isDark = true) { + WalletManageButtons(buttons = buttons) + } +} + +private class WalletManageButtonProvider : CollectionPreviewParameterProvider>( + collection = listOf(WalletPreviewData.manageButtons), +) \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt index a10b91ab37..a1bcc27c31 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt @@ -53,6 +53,7 @@ internal sealed class WalletStateHolder( * @property wallets list of wallets states * @property contentItems content items * @property notifications notifications + * @property buttons manage buttons */ data class SingleCurrencyContent( override val onBackClick: () -> Unit, @@ -61,5 +62,6 @@ internal sealed class WalletStateHolder( override val wallets: ImmutableList, override val contentItems: ImmutableList, override val notifications: ImmutableList, + val buttons: ImmutableList, ) : WalletStateHolder(onBackClick, topBarConfig, selectedWallet, wallets, contentItems, notifications) } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt index b5cf68559c..7378c104e0 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt @@ -1,28 +1,26 @@ package com.tangem.feature.wallet.presentation.wallet.ui import androidx.activity.compose.BackHandler -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable +import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.composed -import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider -import com.tangem.core.ui.components.RoundedActionButton +import com.tangem.core.ui.components.buttons.actions.ActionConfig +import com.tangem.core.ui.components.buttons.actions.RoundedActionButton +import com.tangem.core.ui.components.notifications.Notification import com.tangem.core.ui.components.transactions.Transaction import com.tangem.core.ui.res.TangemTheme import com.tangem.feature.wallet.impl.R @@ -30,9 +28,11 @@ import com.tangem.feature.wallet.presentation.common.WalletPreviewData import com.tangem.feature.wallet.presentation.common.component.NetworkGroupItem import com.tangem.feature.wallet.presentation.common.component.TokenItem import com.tangem.feature.wallet.presentation.wallet.state.WalletContentItemState +import com.tangem.feature.wallet.presentation.wallet.state.WalletManageButtons import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder import com.tangem.feature.wallet.presentation.wallet.ui.components.WalletCardsList import com.tangem.feature.wallet.presentation.wallet.ui.components.WalletTopBar +import com.tangem.feature.wallet.presentation.wallet.ui.decorations.walletContentItemDecoration /** * Wallet screen @@ -49,15 +49,29 @@ internal fun WalletScreen(state: WalletStateHolder, modifier: Modifier = Modifie topBar = { WalletTopBar(config = state.topBarConfig) }, containerColor = TangemTheme.colors.background.secondary, ) { scaffoldPaddings -> - val lastContentItemIndex = remember(state.contentItems) { state.contentItems.lastIndex } LazyColumn( modifier = modifier - .padding(scaffoldPaddings) + .padding(paddingValues = scaffoldPaddings) .fillMaxSize(), + contentPadding = PaddingValues( + horizontal = TangemTheme.dimens.spacing16, + vertical = TangemTheme.dimens.spacing8, + ), horizontalAlignment = Alignment.CenterHorizontally, ) { - item { WalletCardsList(wallets = state.wallets) } + item { + WalletCardsList( + wallets = state.wallets, + modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12), + ) + } + + if (state is WalletStateHolder.SingleCurrencyContent) { + item { WalletManageButtons(buttons = state.buttons) } + } + + items(items = state.notifications, itemContent = { Notification(state = it.state) }) itemsIndexed( items = state.contentItems, @@ -70,36 +84,19 @@ internal fun WalletScreen(state: WalletStateHolder, modifier: Modifier = Modifie is WalletContentItemState.SingleCurrencyItem.Transaction -> index } }, - ) { index, item -> - val itemModifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing16) - .clipFirstAndLastItems(index, lastContentItemIndex) - - when (item) { - is WalletContentItemState.MultiCurrencyItem.NetworkGroupTitle -> { - NetworkGroupItem(networkName = item.networkName, modifier = itemModifier) - } - is WalletContentItemState.MultiCurrencyItem.Token -> { - TokenItem(state = item.state, modifier = itemModifier) - } - is WalletContentItemState.SingleCurrencyItem.Title -> { - SingleCurrencyTitle(config = item, modifier = itemModifier) - } - is WalletContentItemState.SingleCurrencyItem.TransactionGroupTitle -> { - TransactionGroupTitle(config = item, modifier = itemModifier) - } - is WalletContentItemState.SingleCurrencyItem.Transaction -> { - Transaction(state = item.state, modifier = itemModifier) - } - } - } + itemContent = { index, item -> + ContentItem(currentIndex = index, lastIndex = state.contentItems.lastIndex, item = item) + }, + ) if (state is WalletStateHolder.MultiCurrencyContent) { item { RoundedActionButton( - text = stringResource(id = R.string.organize_tokens_title), - iconResId = R.drawable.ic_filter_24, - onClick = state.onOrganizeTokensClick, + config = ActionConfig( + text = stringResource(id = R.string.organize_tokens_title), + iconResId = R.drawable.ic_filter_24, + onClick = state.onOrganizeTokensClick, + ), modifier = Modifier.padding(top = TangemTheme.dimens.spacing14), ) } @@ -108,6 +105,29 @@ internal fun WalletScreen(state: WalletStateHolder, modifier: Modifier = Modifie } } +@Composable +private fun ContentItem(currentIndex: Int, lastIndex: Int, item: WalletContentItemState) { + val itemModifier = Modifier.walletContentItemDecoration(currentIndex, lastIndex) + + when (item) { + is WalletContentItemState.MultiCurrencyItem.NetworkGroupTitle -> { + NetworkGroupItem(networkName = item.networkName, modifier = itemModifier) + } + is WalletContentItemState.MultiCurrencyItem.Token -> { + TokenItem(state = item.state, modifier = itemModifier) + } + is WalletContentItemState.SingleCurrencyItem.Title -> { + SingleCurrencyTitle(config = item, modifier = itemModifier) + } + is WalletContentItemState.SingleCurrencyItem.TransactionGroupTitle -> { + TransactionGroupTitle(config = item, modifier = itemModifier) + } + is WalletContentItemState.SingleCurrencyItem.Transaction -> { + Transaction(state = item.state, modifier = itemModifier) + } + } +} + @Composable private fun SingleCurrencyTitle( config: WalletContentItemState.SingleCurrencyItem.Title, @@ -166,31 +186,6 @@ private fun TransactionGroupTitle( ) } -private fun Modifier.clipFirstAndLastItems(index: Int, lastItemIndex: Int): Modifier = composed { - when (index) { - 0 -> { - this - .padding(top = TangemTheme.dimens.spacing14) - .clip( - RoundedCornerShape( - topStart = TangemTheme.dimens.radius16, - topEnd = TangemTheme.dimens.radius16, - ), - ) - } - lastItemIndex -> { - this - .clip( - RoundedCornerShape( - bottomStart = TangemTheme.dimens.radius16, - bottomEnd = TangemTheme.dimens.radius16, - ), - ) - } - else -> this - } -} - // region Preview @Preview(showBackground = true, widthDp = 360) @Composable diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletCardsList.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletCardsList.kt index d37d359252..bbb62e7aa9 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletCardsList.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/WalletCardsList.kt @@ -23,21 +23,21 @@ import kotlinx.collections.immutable.persistentListOf /** * Wallets list * - * @param wallets list of wallet state + * @param wallets list of wallet state + * @param modifier modifier * [REDACTED_AUTHOR] */ @OptIn(ExperimentalFoundationApi::class) @Composable -internal fun WalletCardsList(wallets: ImmutableList) { +internal fun WalletCardsList(wallets: ImmutableList, modifier: Modifier = Modifier) { val horizontalCardPadding = TangemTheme.dimens.spacing16 val itemWidth = LocalConfiguration.current.screenWidthDp.dp - horizontalCardPadding * 2 val lazyListState = rememberLazyListState() LazyRow( - modifier = Modifier.background(color = TangemTheme.colors.background.secondary), + modifier = modifier.background(color = TangemTheme.colors.background.secondary), state = lazyListState, - contentPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing16), horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8), flingBehavior = rememberSnapFlingBehavior(lazyListState = lazyListState), ) { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/decorations/WalletContentItemDecoration.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/decorations/WalletContentItemDecoration.kt new file mode 100644 index 0000000000..9ec810b323 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/decorations/WalletContentItemDecoration.kt @@ -0,0 +1,36 @@ +package com.tangem.feature.wallet.presentation.wallet.ui.decorations + +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import androidx.compose.ui.draw.clip +import com.tangem.core.ui.res.TangemTheme + +/** +[REDACTED_AUTHOR] + */ +internal fun Modifier.walletContentItemDecoration(currentIndex: Int, lastItemIndex: Int): Modifier = composed { + when (currentIndex) { + 0 -> { + this + .padding(top = TangemTheme.dimens.spacing14) + .clip( + RoundedCornerShape( + topStart = TangemTheme.dimens.radius16, + topEnd = TangemTheme.dimens.radius16, + ), + ) + } + lastItemIndex -> { + this + .clip( + RoundedCornerShape( + bottomStart = TangemTheme.dimens.radius16, + bottomEnd = TangemTheme.dimens.radius16, + ), + ) + } + else -> this + } +} \ No newline at end of file