Updated on 2026-08-14
This commit is contained in:
commit
d73ab1aee6
9 changed files with 1113 additions and 0 deletions
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
|
|
@ -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<InputRowDefaultPreviewData> {
|
||||
override val values: Sequence<InputRowDefaultPreviewData>
|
||||
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
|
||||
|
|
@ -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<InputRowEnterPreviewData> {
|
||||
override val values: Sequence<InputRowEnterPreviewData>
|
||||
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
|
||||
|
|
@ -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<InputRowEnterInfoPreviewData> {
|
||||
override val values: Sequence<InputRowEnterInfoPreviewData>
|
||||
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
|
||||
|
|
@ -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<InputRowImagePreviewData> {
|
||||
override val values: Sequence<InputRowImagePreviewData>
|
||||
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
|
||||
|
|
@ -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<InputRowRecipientPreviewData> {
|
||||
override val values: Sequence<InputRowRecipientPreviewData>
|
||||
get() = sequenceOf(
|
||||
InputRowRecipientPreviewData(
|
||||
value = "",
|
||||
isError = false,
|
||||
),
|
||||
InputRowRecipientPreviewData(
|
||||
value = "0x391316d97a07027a0702c8A002c8A0C25d8470",
|
||||
isError = false,
|
||||
),
|
||||
InputRowRecipientPreviewData(
|
||||
value = "0x391316d97a07027a0702c8A002c8A0C25d8470",
|
||||
isError = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
//endregion
|
||||
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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("") },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue