Updated on 2026-08-14

This commit is contained in:
Tangem 2022-04-13 10:30:27 +03:00
parent 35d74021ac
commit 0a25bbedbb
17 changed files with 224 additions and 173 deletions

View file

@ -0,0 +1,31 @@
package com.tangem.tap.common.compose
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import com.tangem.blockchain.common.Blockchain
import com.tangem.domain.common.form.Field
@Composable
fun BlockchainSpinner(
@StringRes title: Int,
itemList: List<Blockchain>,
selectedItem: Field.Data<Blockchain>,
isEnabled: Boolean = true,
textFieldConverter: (Blockchain) -> String,
dropdownItemView: @Composable ((Blockchain) -> Unit)? = null,
onItemSelected: (Blockchain) -> Unit,
) {
OutlinedSpinner(
modifier = Modifier.fillMaxWidth(),
label = stringResource(id = title),
itemList = itemList,
selectedItem = selectedItem,
textFieldConverter = textFieldConverter,
dropdownItemView = dropdownItemView,
isEnabled = isEnabled,
onItemSelected = onItemSelected
)
}

View file

@ -4,8 +4,8 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.LocalTextStyle
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.*
@ -22,6 +22,7 @@ import com.tangem.domain.DomainStateDialog
import com.tangem.domain.redux.domainStore
import com.tangem.domain.redux.global.DomainGlobalAction
import com.tangem.domain.redux.global.DomainGlobalState
import com.tangem.tap.features.tokens.addCustomToken.compose.SelectTokenNetworkDialog
import org.rekotlin.StoreSubscriber
@Composable
@ -56,15 +57,7 @@ fun ShowTheDialog(dialogState: MutableState<DomainStateDialog?>) {
val onDismissRequest = { domainStore.dispatch(DomainGlobalAction.ShowDialog(null)) }
when (val dialog = dialogState.value) {
is DomainDialog.SelectTokenDialog -> {
SimpleDialog(
title = "Select a token",
items = dialog.items,
itemNameConverter = dialog.itemNameConverter,
onSelect = dialog.onSelect,
onDismissRequest = onDismissRequest
)
}
is DomainDialog.SelectTokenDialog -> SelectTokenNetworkDialog(dialog, onDismissRequest)
}
}
@ -75,9 +68,9 @@ fun ShowTheDialog(dialogState: MutableState<DomainStateDialog?>) {
fun <T> SimpleDialog(
title: String,
items: List<T>,
itemNameConverter: (T) -> String,
onSelect: (T) -> Unit,
onDismissRequest: () -> Unit
onDismissRequest: () -> Unit,
itemContent: @Composable (T) -> Unit,
) {
Dialog(
properties = DialogProperties(false, false),
@ -85,7 +78,7 @@ fun <T> SimpleDialog(
) {
Surface(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(8.dp)
shape = MaterialTheme.shapes.medium
) {
Column(
modifier = Modifier.padding(22.dp)
@ -112,11 +105,7 @@ fun <T> SimpleDialog(
onDismissRequest()
},
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = itemNameConverter(item),
)
}
) { itemContent(item) }
}
}
}

View file

@ -5,6 +5,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.extensions.VoidCallback
@ -14,17 +16,16 @@ import com.tangem.tap.common.extensions.ValueCallback
/**
[REDACTED_AUTHOR]
*/
private class OutlinedSpinner
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun <T> OutlinedSpinner(
modifier: Modifier = Modifier,
title: String,
label: String,
itemList: List<T>,
selectedItem: Field.Data<T>,
onItemSelected: ValueCallback<T>,
itemNameConverter: (T) -> String = { it.toString() },
textFieldConverter: (T) -> String = { it.toString() },
dropdownItemView: @Composable ((T) -> Unit)? = null,
isEnabled: Boolean = true,
onClose: VoidCallback = {}
) {
@ -48,24 +49,27 @@ fun <T> OutlinedSpinner(
expanded = rIsExpanded.value,
onExpandedChange = { rIsExpanded.value = !rIsExpanded.value },
) {
OutlinedTextField(
modifier = modifier,
readOnly = true,
enabled = isEnabled,
value = itemNameConverter(rSelectedItem.value),
onValueChange = {},
label = { Text(title) },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = rIsExpanded.value) },
)
ProvideTextStyle(value = TextStyle(color = Color.Blue)) {
OutlinedTextField(
modifier = modifier,
readOnly = true,
enabled = isEnabled,
value = textFieldConverter(rSelectedItem.value),
onValueChange = {},
label = { Text(label) },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = rIsExpanded.value) },
)
}
ExposedDropdownMenu(
expanded = rIsExpanded.value,
onDismissRequest = onDismissRequest,
) {
itemList.forEach { item ->
DropdownMenuItem(
onClick = { onItemSelectedInternal(item) }
) {
Text(itemNameConverter(item))
DropdownMenuItem(onClick = { onItemSelectedInternal(item) }) {
when (dropdownItemView) {
null -> Text(textFieldConverter(item))
else -> dropdownItemView(item)
}
}
}
}
@ -77,7 +81,7 @@ fun <T> OutlinedSpinner(
fun TestSpinnerPreview() {
Scaffold() {
OutlinedSpinner(
title = "Blockchain name",
label = "Blockchain name",
itemList = listOf(Blockchain.values()),
selectedItem = Field.Data(Blockchain.Avalanche),
onItemSelected = {},

View file

@ -28,8 +28,6 @@ import com.tangem.tap.common.compose.extensions.stringResourceDefault
/**
[REDACTED_AUTHOR]
*/
private class OutlinedTextFieldWidget
@Composable
fun OutlinedTextFieldWidget(
modifier: Modifier = Modifier,
@ -90,7 +88,7 @@ private fun OutlinedProgressTextField(
val rTextDebouncer = valueDebouncerAsState(debounce, onTextChanged)
val rText = remember { mutableStateOf(textFieldData.value) }
fun updateFieldValueAndEmmit(value: String){
fun updateFieldValueAndEmmit(value: String) {
rText.value = value
rTextDebouncer.emmit(value)
}

View file

@ -40,28 +40,28 @@ fun SpacerH24(modifier: Modifier = Modifier) {
// ***************************** Vertical
@Composable
fun SpacerV(width: Dp, modifier: Modifier = Modifier) {
fun SpacerW(width: Dp, modifier: Modifier = Modifier) {
Spacer(modifier = modifier.width(width))
}
@Composable
fun SpacerV4(modifier: Modifier = Modifier) {
SpacerV(4.dp, modifier)
fun SpacerW4(modifier: Modifier = Modifier) {
SpacerW(4.dp, modifier)
}
@Composable
fun SpacerV8(modifier: Modifier = Modifier) {
SpacerV(8.dp, modifier)
fun SpacerW8(modifier: Modifier = Modifier) {
SpacerW(8.dp, modifier)
}
@Composable
fun SpacerV16(modifier: Modifier = Modifier) {
SpacerV(16.dp, modifier)
fun SpacerW16(modifier: Modifier = Modifier) {
SpacerW(16.dp, modifier)
}
@Composable
fun SpacerV24(modifier: Modifier = Modifier) {
SpacerV(24.dp, modifier)
fun SpacerW24(modifier: Modifier = Modifier) {
SpacerW(24.dp, modifier)
}
// ***************************** Size

View file

@ -0,0 +1,27 @@
package com.tangem.tap.common.compose
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.sp
/**
[REDACTED_AUTHOR]
* Compose views are not typically used as a main or base view.
*/
@Composable
fun TitleSubtitle(
title: String,
subtitle: String
) {
Column() {
Text(text = title)
Text(
text = subtitle,
fontSize = 12.sp,
color = Color.Gray
)
}
}