diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/fields/SimpleTextField.kt b/core/ui/src/main/java/com/tangem/core/ui/components/fields/SimpleTextField.kt new file mode 100644 index 0000000000..7e0e1643c6 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/fields/SimpleTextField.kt @@ -0,0 +1,60 @@ +package com.tangem.core.ui.components.fields + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.text.input.VisualTransformation +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme + +/** + * Simple text field with placeholder + */ +@Composable +fun SimpleTextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + placeholder: TextReference? = null, + singleLine: Boolean = false, + visualTransformation: VisualTransformation = VisualTransformation.None, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + color: Color = TangemTheme.colors.text.primary1, + readOnly: Boolean = false, +) { + val focusRequester = remember { FocusRequester() } + BasicTextField( + value = value, + onValueChange = onValueChange, + textStyle = TangemTheme.typography.body2.copy(color = color), + cursorBrush = SolidColor(TangemTheme.colors.text.primary1), + singleLine = singleLine, + readOnly = readOnly, + visualTransformation = visualTransformation, + keyboardOptions = keyboardOptions, + decorationBox = { textValue -> + Box { + if (value.isBlank() && placeholder != null) { + Text( + text = placeholder.resolveReference(), + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.disabled, + modifier = Modifier, + ) + } + textValue() + } + }, + modifier = modifier + .focusRequester(focusRequester), + ) +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowDefault.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowDefault.kt new file mode 100644 index 0000000000..e41ac02d17 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowDefault.kt @@ -0,0 +1,152 @@ +package com.tangem.core.ui.components.inputrow + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.* +import androidx.compose.material.ripple.rememberRipple +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import com.tangem.core.ui.R +import com.tangem.core.ui.components.inputrow.inner.DividerContainer +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme + +/** + * [InputRowDefault](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=2100-807&mode=design&t=86eKp9izWxUvmoCq-4) + * + * @param title title reference + * @param text primary text reference + * @param modifier modifier + * @param titleColor title color + * @param textColor text color + * @param iconRes action icon + * @param iconTint action icon tint + * @param onIconClick click on action icon + * @param showDivider show divider + * @see [InputRowEnter] for editable version + */ +@Composable +fun InputRowDefault( + title: TextReference, + text: TextReference, + modifier: Modifier = Modifier, + titleColor: Color = TangemTheme.colors.text.secondary, + textColor: Color = TangemTheme.colors.text.primary1, + iconRes: Int? = null, + iconTint: Color = TangemTheme.colors.icon.informative, + onIconClick: (() -> Unit)? = null, + showDivider: Boolean = false, +) { + DividerContainer( + modifier = modifier, + showDivider = showDivider, + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(TangemTheme.dimens.spacing12), + ) { + Column( + modifier = Modifier + .weight(1f), + ) { + Text( + text = title.resolveReference(), + style = TangemTheme.typography.caption2, + color = titleColor, + ) + Text( + text = text.resolveReference(), + style = TangemTheme.typography.body2, + color = textColor, + modifier = Modifier.padding(top = TangemTheme.dimens.spacing8), + ) + } + iconRes?.let { + Icon( + painter = painterResource(id = iconRes), + contentDescription = null, + tint = iconTint, + modifier = Modifier + .padding( + top = TangemTheme.dimens.spacing10, + bottom = TangemTheme.dimens.spacing10, + ) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(bounded = false), + ) { onIconClick?.invoke() }, + ) + } + } + } +} + +//region preview +@Preview +@Composable +private fun InputRowDefaultPreview_Light( + @PreviewParameter(InputRowDefaultPreviewDataProvider::class) data: InputRowDefaultPreviewData, +) { + TangemTheme { + InputRowDefault( + title = TextReference.Str(data.title), + text = TextReference.Str(data.text), + iconRes = data.iconRes, + showDivider = data.showDivider, + modifier = Modifier.background(TangemTheme.colors.background.action), + ) + } +} + +@Preview +@Composable +private fun InputRowDefaultPreview_Dark( + @PreviewParameter(InputRowDefaultPreviewDataProvider::class) data: InputRowDefaultPreviewData, +) { + TangemTheme(isDark = true) { + InputRowDefault( + title = TextReference.Str(data.title), + text = TextReference.Str(data.text), + iconRes = data.iconRes, + showDivider = data.showDivider, + modifier = Modifier.background(TangemTheme.colors.background.action), + ) + } +} + +private data class InputRowDefaultPreviewData( + val title: String, + val text: String, + val iconRes: Int?, + val showDivider: Boolean, +) + +private class InputRowDefaultPreviewDataProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + InputRowDefaultPreviewData( + title = "title", + text = "text", + iconRes = null, + showDivider = true, + ), + InputRowDefaultPreviewData( + title = "title", + text = "text", + iconRes = R.drawable.ic_chevron_right_24, + showDivider = false, + ), + ) +} +//endregion \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnter.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnter.kt new file mode 100644 index 0000000000..f81372c3da --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnter.kt @@ -0,0 +1,167 @@ +package com.tangem.core.ui.components.inputrow + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.ripple.rememberRipple +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import com.tangem.core.ui.R +import com.tangem.core.ui.components.inputrow.inner.DividerContainer +import com.tangem.core.ui.components.fields.SimpleTextField +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme + +/** + * [InputRowEnter](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=2100-799&mode=design&t=IQ5lBJEkFGU4WSvi-4) + * + * @param title title reference + * @param text primary text reference + * @param onValueChange text change callback + * @param modifier modifier + * @param titleColor title color + * @param textColor text color + * @param isSingleLine text + * @param visualTransformation applied transformation to text + * @param keyboardOptions keyboard options for field + * @param iconRes action icon + * @param iconTint action icon tint + * @param onIconClick click on action icon + * @param showDivider show divider + * @see [InputRowDefault] for read only version + */ +@Composable +fun InputRowEnter( + title: TextReference, + text: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + titleColor: Color = TangemTheme.colors.text.secondary, + textColor: Color = TangemTheme.colors.text.primary1, + isSingleLine: Boolean = false, + visualTransformation: VisualTransformation = VisualTransformation.None, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + iconRes: Int? = null, + iconTint: Color = TangemTheme.colors.icon.informative, + onIconClick: (() -> Unit)? = null, + showDivider: Boolean = false, +) { + DividerContainer( + modifier = modifier, + showDivider = showDivider, + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(TangemTheme.dimens.spacing12), + ) { + Column(modifier = Modifier.weight(1f)) { + Text( + text = title.resolveReference(), + style = TangemTheme.typography.caption2, + color = titleColor, + ) + SimpleTextField( + value = text, + onValueChange = onValueChange, + color = textColor, + singleLine = isSingleLine, + visualTransformation = visualTransformation, + keyboardOptions = keyboardOptions, + modifier = Modifier + .padding(top = TangemTheme.dimens.spacing8), + ) + } + iconRes?.let { + Icon( + painter = painterResource(id = iconRes), + contentDescription = null, + tint = iconTint, + modifier = Modifier + .padding( + top = TangemTheme.dimens.spacing10, + bottom = TangemTheme.dimens.spacing10, + ) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(bounded = false), + ) { onIconClick?.invoke() }, + ) + } + } + } +} + +//region preview +@Preview +@Composable +private fun InputRowEnterPreview_Light( + @PreviewParameter(InputRowEnterPreviewDataProvider::class) data: InputRowEnterPreviewData, +) { + TangemTheme { + InputRowEnter( + title = TextReference.Str(data.title), + text = data.text, + iconRes = data.iconRes, + showDivider = data.showDivider, + onValueChange = {}, + modifier = Modifier.background(TangemTheme.colors.background.action), + ) + } +} + +@Preview +@Composable +private fun InputRowEnterPreview_Dark( + @PreviewParameter(InputRowEnterPreviewDataProvider::class) data: InputRowEnterPreviewData, +) { + TangemTheme(isDark = true) { + InputRowEnter( + title = TextReference.Str(data.title), + text = data.text, + iconRes = data.iconRes, + showDivider = data.showDivider, + onValueChange = {}, + modifier = Modifier.background(TangemTheme.colors.background.action), + ) + } +} + +private data class InputRowEnterPreviewData( + val title: String, + val text: String, + val iconRes: Int?, + val showDivider: Boolean, +) + +private class InputRowEnterPreviewDataProvider : + PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + InputRowEnterPreviewData( + title = "title", + text = "text", + iconRes = null, + showDivider = true, + ), + InputRowEnterPreviewData( + title = "title", + text = "text", + iconRes = R.drawable.ic_chevron_right_24, + showDivider = false, + ), + ) +} +//endregion \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnterInfo.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnterInfo.kt new file mode 100644 index 0000000000..25debb16dc --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowEnterInfo.kt @@ -0,0 +1,153 @@ +package com.tangem.core.ui.components.inputrow + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import com.tangem.core.ui.components.inputrow.inner.DividerContainer +import com.tangem.core.ui.components.fields.SimpleTextField +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme + +/** + * Input Row Enter with Info variation. + * [Input Row Enter](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=2100-799&mode=design&t=IQ5lBJEkFGU4WSvi-4) + * [Input Row Enter Info](https://www.figma.com/file/Vs6SkVsFnUPsSCNwlnVf5U/Android-%E2%80%93-UI?type=design&node-id=7854-33577&mode=design&t=6o23sqF8fDQdn4C5-4) + * + * @param title title reference + * @param text primary text reference + * @param onValueChange text change callback + * @param modifier modifier + * @param titleColor title color + * @param textColor text color + * @param isSingleLine text + * @param visualTransformation applied transformation to text + * @param keyboardOptions keyboard options for field + * @param showDivider show divider + */ +@Composable +fun InputRowEnterInfo( + title: TextReference, + text: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + info: TextReference? = null, + titleColor: Color = TangemTheme.colors.text.secondary, + textColor: Color = TangemTheme.colors.text.primary1, + infoColor: Color = TangemTheme.colors.text.tertiary, + isSingleLine: Boolean = false, + visualTransformation: VisualTransformation = VisualTransformation.None, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + showDivider: Boolean = false, +) { + DividerContainer( + modifier = modifier, + showDivider = showDivider, + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(TangemTheme.dimens.spacing12), + ) { + Text( + text = title.resolveReference(), + style = TangemTheme.typography.caption2, + color = titleColor, + ) + Row { + SimpleTextField( + value = text, + onValueChange = onValueChange, + singleLine = isSingleLine, + color = textColor, + visualTransformation = visualTransformation, + keyboardOptions = keyboardOptions, + modifier = Modifier + .padding(top = TangemTheme.dimens.spacing8) + .weight(1f), + ) + info?.let { + Text( + text = it.resolveReference(), + style = TangemTheme.typography.body2, + color = infoColor, + modifier = Modifier + .padding(start = TangemTheme.dimens.spacing8) + .align(Alignment.Bottom), + ) + } + } + } + } +} + +//region preview +@Preview +@Composable +private fun InputRowEnterInfoPreview_Light( + @PreviewParameter(InputRowEnterInfoPreviewDataProvider::class) data: InputRowEnterInfoPreviewData, +) { + TangemTheme { + InputRowEnterInfo( + title = data.title, + text = data.text, + info = data.info, + showDivider = data.showDivider, + onValueChange = {}, + modifier = Modifier.background(TangemTheme.colors.background.action), + ) + } +} + +@Preview +@Composable +private fun InputRowEnterInfoPreview_Dark( + @PreviewParameter(InputRowEnterInfoPreviewDataProvider::class) data: InputRowEnterInfoPreviewData, +) { + TangemTheme(isDark = true) { + InputRowEnterInfo( + title = data.title, + text = data.text, + info = data.info, + showDivider = data.showDivider, + onValueChange = {}, + modifier = Modifier.background(TangemTheme.colors.background.action), + ) + } +} + +private data class InputRowEnterInfoPreviewData( + val title: TextReference, + val text: String, + val showDivider: Boolean, + val info: TextReference?, +) + +private class InputRowEnterInfoPreviewDataProvider : + PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + InputRowEnterInfoPreviewData( + title = TextReference.Str("title"), + text = "text", + showDivider = true, + info = TextReference.Str("info"), + ), + InputRowEnterInfoPreviewData( + title = TextReference.Str("title"), + text = "text", + showDivider = false, + info = null, + ), + ) +} +//endregion \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImage.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImage.kt new file mode 100644 index 0000000000..1754c3b8bc --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImage.kt @@ -0,0 +1,196 @@ +package com.tangem.core.ui.components.inputrow + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.* +import androidx.compose.material.ripple.rememberRipple +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment.Companion.CenterVertically +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import com.tangem.core.ui.R +import com.tangem.core.ui.components.inputrow.inner.DividerContainer +import com.tangem.core.ui.components.currency.tokenicon.TokenIcon +import com.tangem.core.ui.components.currency.tokenicon.TokenIconState +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme + +/** + * [Input Row Image](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=2100-813&mode=design&t=IQ5lBJEkFGU4WSvi-4) + * + * @param title title reference + * @param subtitle subtitle reference + * @param caption caption reference + * @param tokenIconState token icon state [TokenIconState] + * @param modifier modifier + * @param titleColor title color + * @param subtitleColor subtitle color + * @param captionColor caption color + * @param iconRes action icon + * @param iconTint action icon tint + * @param onIconClick click on action icon + * @param showNetworkIcon show token network icon + * @param showDivider show divider + */ +@Composable +fun InputRowImage( + title: TextReference, + subtitle: TextReference, + caption: TextReference, + tokenIconState: TokenIconState, + modifier: Modifier = Modifier, + titleColor: Color = TangemTheme.colors.text.secondary, + subtitleColor: Color = TangemTheme.colors.text.primary1, + captionColor: Color = TangemTheme.colors.text.tertiary, + iconRes: Int? = null, + iconTint: Color = TangemTheme.colors.icon.informative, + onIconClick: (() -> Unit)? = null, + showNetworkIcon: Boolean = false, + showDivider: Boolean = false, +) { + DividerContainer( + modifier = modifier, + showDivider = showDivider, + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(TangemTheme.dimens.spacing12), + ) { + Text( + text = title.resolveReference(), + style = TangemTheme.typography.caption2, + color = titleColor, + ) + Row( + modifier = Modifier + .padding( + top = TangemTheme.dimens.spacing6, + ), + ) { + TokenIcon( + state = tokenIconState, + shouldDisplayNetwork = showNetworkIcon, + modifier = Modifier + .size(TangemTheme.dimens.size36), + ) + Column( + modifier = Modifier + .weight(1f) + .padding(start = TangemTheme.dimens.spacing12), + ) { + Text( + text = subtitle.resolveReference(), + style = TangemTheme.typography.subtitle2, + color = subtitleColor, + ) + Text( + text = caption.resolveReference(), + style = TangemTheme.typography.caption2, + color = captionColor, + modifier = Modifier.padding(top = TangemTheme.dimens.spacing2), + ) + } + iconRes?.let { + Icon( + painter = painterResource(id = iconRes), + contentDescription = null, + tint = iconTint, + modifier = Modifier + .align(CenterVertically) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(bounded = false), + ) { onIconClick?.invoke() }, + ) + } + } + } + } +} + +//region preview +@Preview +@Composable +private fun InputRowInputEnterInfoPreview_Light( + @PreviewParameter(InputRowImagePreviewDataProvider::class) data: InputRowImagePreviewData, +) { + TangemTheme { + InputRowImage( + title = data.title, + modifier = Modifier.background(TangemTheme.colors.background.action), + subtitle = data.subtitle, + caption = data.caption, + tokenIconState = data.iconState, + iconRes = data.actionIconRes, + onIconClick = {}, + showNetworkIcon = false, + showDivider = data.showDivider, + ) + } +} + +@Preview +@Composable +private fun InputRowImagePreview_Dark( + @PreviewParameter(InputRowImagePreviewDataProvider::class) data: InputRowImagePreviewData, +) { + TangemTheme(isDark = true) { + InputRowImage( + title = data.title, + modifier = Modifier.background(TangemTheme.colors.background.action), + subtitle = data.subtitle, + caption = data.caption, + tokenIconState = data.iconState, + iconRes = data.actionIconRes, + onIconClick = {}, + showNetworkIcon = false, + showDivider = data.showDivider, + ) + } +} + +private data class InputRowImagePreviewData( + val title: TextReference, + val subtitle: TextReference, + val caption: TextReference, + val iconState: TokenIconState, + val showDivider: Boolean, + val actionIconRes: Int?, + val showNetworkIcon: Boolean = false, +) + +private class InputRowImagePreviewDataProvider : + PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + InputRowImagePreviewData( + title = TextReference.Str("title"), + subtitle = TextReference.Str("subtitle"), + caption = TextReference.Str("caption"), + iconState = TokenIconState.Locked, + actionIconRes = null, + showDivider = false, + showNetworkIcon = false, + ), + InputRowImagePreviewData( + title = TextReference.Str("title"), + subtitle = TextReference.Str("subtitle"), + caption = TextReference.Str("caption"), + iconState = TokenIconState.Locked, + actionIconRes = R.drawable.ic_chevron_right_24, + showDivider = true, + showNetworkIcon = true, + ), + ) +} +//endregion \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowRecipient.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowRecipient.kt new file mode 100644 index 0000000000..312b0c0db1 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowRecipient.kt @@ -0,0 +1,168 @@ +package com.tangem.core.ui.components.inputrow + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment.Companion.CenterVertically +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 com.tangem.core.ui.R +import com.tangem.core.ui.components.fields.SimpleTextField +import com.tangem.core.ui.components.icons.identicon.IdentIcon +import com.tangem.core.ui.components.inputrow.inner.DividerContainer +import com.tangem.core.ui.components.inputrow.inner.PasteButton +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme + +/** + * [Input Row Recipient](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=2100-826&mode=design&t=IQ5lBJEkFGU4WSvi-4) + * + * @param title title reference + * @param value recipient address + * @param placeholder placeholder + * @param onValueChange callback for value change + * @param onPasteClick callback for paste + * @param modifier composable modifier + * @param singleLine is single line text + * @param error error text + * @param isError is error flag + * @param showDivider show divider + * + * @see InputRowRecipientDefault for readonly version + */ +@Composable +fun InputRowRecipient( + title: TextReference, + value: String, + placeholder: TextReference, + onValueChange: (String) -> Unit, + onPasteClick: (String) -> Unit, + modifier: Modifier = Modifier, + singleLine: Boolean = false, + error: TextReference? = null, + isError: Boolean = false, + showDivider: Boolean = false, +) { + val (titleText, color) = if (isError && error != null) { + error to TangemTheme.colors.text.warning + } else { + title to TangemTheme.colors.text.secondary + } + DividerContainer( + modifier = modifier, + showDivider = showDivider, + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(TangemTheme.dimens.spacing12), + ) { + Text( + text = titleText.resolveReference(), + style = TangemTheme.typography.caption2, + color = color, + ) + Row( + modifier = Modifier + .padding(top = TangemTheme.dimens.spacing8), + ) { + IdentIcon( + address = value, + modifier = Modifier + .align(CenterVertically) + .clip(RoundedCornerShape(TangemTheme.dimens.radius18)) + .size(TangemTheme.dimens.size36) + .background(TangemTheme.colors.background.tertiary), + ) + SimpleTextField( + value = value, + placeholder = placeholder, + onValueChange = onValueChange, + singleLine = singleLine, + modifier = Modifier + .padding(start = TangemTheme.dimens.spacing12) + .weight(1f) + .align(CenterVertically), + ) + PasteButton( + isPasteButtonVisible = value.isBlank(), + onClick = onPasteClick, + modifier = Modifier + .align(CenterVertically) + .padding(start = TangemTheme.dimens.spacing8), + ) + } + } + } +} + +//region preview +@Preview +@Composable +private fun InputRowRecipientPreview_Light( + @PreviewParameter(InputRowRecipientPreviewDataProvider::class) value: InputRowRecipientPreviewData, +) { + TangemTheme { + InputRowRecipient( + value = value.value, + title = TextReference.Res(R.string.send_recipient), + placeholder = TextReference.Res(R.string.send_optional_field), + error = TextReference.Str("Error"), + isError = value.isError, + showDivider = true, + onValueChange = {}, + onPasteClick = {}, + modifier = Modifier.background(TangemTheme.colors.background.primary), + ) + } +} + +@Preview +@Composable +private fun InputRowRecipientPreview_Dark( + @PreviewParameter(InputRowRecipientPreviewDataProvider::class) value: InputRowRecipientPreviewData, +) { + TangemTheme(isDark = true) { + InputRowRecipient( + value = value.value, + title = TextReference.Res(R.string.send_recipient), + placeholder = TextReference.Res(R.string.send_optional_field), + error = TextReference.Str("Error"), + isError = value.isError, + showDivider = true, + onValueChange = {}, + onPasteClick = {}, + modifier = Modifier.background(TangemTheme.colors.background.primary), + ) + } +} + +private data class InputRowRecipientPreviewData( + val value: String, + val isError: Boolean, +) + +private class InputRowRecipientPreviewDataProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + InputRowRecipientPreviewData( + value = "", + isError = false, + ), + InputRowRecipientPreviewData( + value = "0x391316d97a07027a0702c8A002c8A0C25d8470", + isError = false, + ), + InputRowRecipientPreviewData( + value = "0x391316d97a07027a0702c8A002c8A0C25d8470", + isError = true, + ), + ) +} +//endregion \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowRecipientDefault.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowRecipientDefault.kt new file mode 100644 index 0000000000..8ae6b1b386 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowRecipientDefault.kt @@ -0,0 +1,106 @@ +package com.tangem.core.ui.components.inputrow + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import com.tangem.core.ui.R +import com.tangem.core.ui.components.icons.identicon.IdentIcon +import com.tangem.core.ui.components.inputrow.inner.DividerContainer +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme + +/** + * Read only version of [InputRowRecipient]. + * [Input Row Recipient](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=2100-826&mode + * =design&t=IQ5lBJEkFGU4WSvi-4) + * + * @param title title reference + * @param value recipient address + * @param modifier composable modifier + * @param titleColor title color + * @param showDivider show divider + * @see InputRowRecipient for editable version + */ +@Composable +fun InputRowRecipientDefault( + title: TextReference, + value: String, + modifier: Modifier = Modifier, + titleColor: Color = TangemTheme.colors.text.secondary, + showDivider: Boolean = false, +) { + DividerContainer( + modifier = modifier, + showDivider = showDivider, + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(TangemTheme.dimens.spacing12), + ) { + Text( + text = title.resolveReference(), + style = TangemTheme.typography.caption2, + color = titleColor, + ) + Row( + modifier = Modifier + .padding(top = TangemTheme.dimens.spacing8), + ) { + IdentIcon( + address = value, + modifier = Modifier + .align(Alignment.CenterVertically) + .clip(RoundedCornerShape(TangemTheme.dimens.radius18)) + .size(TangemTheme.dimens.size36) + .background(TangemTheme.colors.background.tertiary), + ) + Text( + text = value, + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.primary1, + modifier = Modifier + .padding(start = TangemTheme.dimens.spacing12) + .weight(1f) + .align(Alignment.CenterVertically), + ) + } + } + } +} + +//region preview +@Preview +@Composable +private fun InputRowRecipientPreview_Light() { + TangemTheme { + InputRowRecipientDefault( + value = "0x391316d97a07027a0702c8A002c8A0C25d8470", + title = TextReference.Res(R.string.send_recipient), + showDivider = true, + modifier = Modifier.background(TangemTheme.colors.background.primary), + ) + } +} + +@Preview +@Composable +private fun InputRowRecipientPreview_Dark() { + TangemTheme(isDark = true) { + InputRowRecipientDefault( + value = "0x391316d97a07027a0702c8A002c8A0C25d8470", + title = TextReference.Res(R.string.send_recipient), + showDivider = false, + modifier = Modifier.background(TangemTheme.colors.background.primary), + ) + } +} +//endregion \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/DividerContainer.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/DividerContainer.kt new file mode 100644 index 0000000000..a5510a378d --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/DividerContainer.kt @@ -0,0 +1,31 @@ +package com.tangem.core.ui.components.inputrow.inner + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Divider +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import com.tangem.core.ui.res.TangemTheme + +@Composable +fun DividerContainer( + modifier: Modifier = Modifier, + showDivider: Boolean = false, + paddingValues: PaddingValues = PaddingValues(start = TangemTheme.dimens.spacing12), + content: @Composable () -> Unit, +) { + Box(modifier = modifier) { + content() + if (showDivider) { + Divider( + modifier = Modifier + .align(Alignment.BottomCenter) + .padding(paddingValues), + color = TangemTheme.colors.stroke.primary, + thickness = TangemTheme.dimens.size0_5, + ) + } + } +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/PasteButton.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/PasteButton.kt new file mode 100644 index 0000000000..3e4642c061 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/PasteButton.kt @@ -0,0 +1,80 @@ +package com.tangem.core.ui.components.inputrow.inner + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.ripple.rememberRipple +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.platform.LocalHapticFeedback +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import com.tangem.core.ui.R +import com.tangem.core.ui.res.TangemTheme + +/** + * Paste button with cross icon. Retrieves text from clipboard. + * [Paste button](https://www.figma.com/file/Vs6SkVsFnUPsSCNwlnVf5U/Android-%E2%80%93-UI?type=design&node-id=7853-33535&mode=design&t=6o23sqF8fDQdn4C5-4) + * + * @param isPasteButtonVisible is paste button visible + * @param onClick action callback + * @param modifier composable modifier + */ +@Composable +fun PasteButton(isPasteButtonVisible: Boolean, onClick: (String) -> Unit, modifier: Modifier = Modifier) { + val clipboardManager = LocalClipboardManager.current + val hapticFeedback = LocalHapticFeedback.current + + if (isPasteButtonVisible) { + Box(modifier = modifier) { + Text( + text = "Paste", + style = TangemTheme.typography.button, + color = TangemTheme.colors.text.primary2, + modifier = Modifier + .background( + color = TangemTheme.colors.button.primary, + shape = TangemTheme.shapes.roundedCornersXMedium, + ) + .padding( + horizontal = TangemTheme.dimens.spacing10, + vertical = TangemTheme.dimens.spacing2, + ) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(radius = TangemTheme.dimens.radius8), + onClick = { + hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) + onClick( + clipboardManager + .getText() + ?.toString() + .orEmpty(), + ) + }, + ), + ) + } + } else { + Icon( + painter = painterResource(id = R.drawable.ic_close_24), + tint = TangemTheme.colors.icon.informative, + contentDescription = stringResource(R.string.common_close), + modifier = modifier + .size(TangemTheme.dimens.size20) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(radius = TangemTheme.dimens.radius10), + onClick = { onClick("") }, + ), + ) + } +} \ No newline at end of file