diff --git a/app/src/main/java/com/tangem/tap/common/compose/OutlinedSpinner.kt b/app/src/main/java/com/tangem/tap/common/compose/OutlinedSpinner.kt index 4c2a91e791..a4d9cc898b 100644 --- a/app/src/main/java/com/tangem/tap/common/compose/OutlinedSpinner.kt +++ b/app/src/main/java/com/tangem/tap/common/compose/OutlinedSpinner.kt @@ -67,6 +67,7 @@ fun OutlinedSpinner( onValueChange = {}, label = { Text(label) }, trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = rIsExpanded.value) }, + colors = TangemTextFieldsDefault.defaultTextFieldColors, ) if (isEnabled) { @@ -104,4 +105,4 @@ fun TestSpinnerPreview() { onItemSelected = {}, ) } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/compose/OutlinedTextFieldWidget.kt b/app/src/main/java/com/tangem/tap/common/compose/OutlinedTextFieldWidget.kt index ecffb1c422..18ec176d52 100644 --- a/app/src/main/java/com/tangem/tap/common/compose/OutlinedTextFieldWidget.kt +++ b/app/src/main/java/com/tangem/tap/common/compose/OutlinedTextFieldWidget.kt @@ -6,6 +6,7 @@ import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutVertically +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth @@ -15,6 +16,7 @@ import androidx.compose.material.LinearProgressIndicator import androidx.compose.material.OutlinedTextField import androidx.compose.material.Scaffold import androidx.compose.material.Text +import androidx.compose.material.TextFieldColors import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -28,6 +30,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.tangem.common.module.ModuleError +import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.common.form.Field import com.tangem.tap.common.CompositionLogger import com.tangem.tap.common.compose.extensions.stringResourceDefault @@ -91,6 +94,8 @@ private fun OutlinedProgressTextField( debounce: Long = 400, visualTransformation: VisualTransformation = VisualTransformation.None, keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + colors: TextFieldColors = TangemTextFieldsDefault.defaultTextFieldColors, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, trailingIcon: @Composable (() -> Unit)? = null, onTextChanged: (String) -> Unit, ) { @@ -160,10 +165,22 @@ private fun OutlinedProgressTextField( textDebouncer.emmit(it) }, keyboardOptions = keyboardOptions, - label = { Text(label) }, + label = { + Text( + text = label, + style = TangemTheme.typography.caption, + color = colors.labelColor( + enabled = isEnabled, + error = error != null, + interactionSource = interactionSource, + ).value, + ) + }, placeholder = { Text( text = placeholder, + style = TangemTheme.typography.body1, + color = colors.placeholderColor(enabled = isEnabled).value, maxLines = 1, overflow = TextOverflow.Ellipsis, ) @@ -173,6 +190,8 @@ private fun OutlinedProgressTextField( enabled = isEnabled, isError = error != null, visualTransformation = visualTransformation, + colors = colors, + interactionSource = interactionSource, ) AnimatedVisibility( modifier = modifier @@ -180,7 +199,11 @@ private fun OutlinedProgressTextField( .align(Alignment.BottomCenter) .padding(start = 6.dp, top = 0.dp, end = 6.dp, bottom = 6.dp), visible = isLoading, - ) { LinearProgressIndicator() } + ) { + LinearProgressIndicator( + color = TangemTheme.colors.icon.primary1, + ) + } } } diff --git a/app/src/main/java/com/tangem/tap/common/compose/TangemTextFieldsDefault.kt b/app/src/main/java/com/tangem/tap/common/compose/TangemTextFieldsDefault.kt new file mode 100644 index 0000000000..694fd8c376 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/compose/TangemTextFieldsDefault.kt @@ -0,0 +1,156 @@ +package com.tangem.tap.common.compose + +import androidx.compose.animation.animateColorAsState +import androidx.compose.animation.core.tween +import androidx.compose.foundation.interaction.InteractionSource +import androidx.compose.foundation.interaction.collectIsFocusedAsState +import androidx.compose.material.TextFieldColors +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.State +import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.ui.graphics.Color +import com.tangem.core.ui.res.TangemTheme + +// Copy from com.tangem.core.ui.components +// TODO: Delete this after fields has been moved to core-ui module +internal object TangemTextFieldsDefault { + val defaultTextFieldColors: TangemTextFieldColors + @Composable @Stable get() = TangemTextFieldColors( + textColor = TangemTheme.colors.text.primary1, + disabledTextColor = TangemTheme.colors.text.disabled, + backgroundColor = Color.Transparent, + cursorColor = TangemTheme.colors.icon.primary1, + errorCursorColor = TangemTheme.colors.icon.warning, + focusedIndicatorColor = TangemTheme.colors.icon.primary1, + unfocusedIndicatorColor = TangemTheme.colors.stroke.primary, + disabledIndicatorColor = TangemTheme.colors.stroke.primary, + errorIndicatorColor = TangemTheme.colors.icon.warning, + leadingIconColor = TangemTheme.colors.icon.informative, + disabledLeadingIconColor = Color.Transparent, + errorLeadingIconColor = TangemTheme.colors.icon.warning, + trailingIconColor = TangemTheme.colors.icon.informative, + disabledTrailingIconColor = Color.Transparent, + errorTrailingIconColor = TangemTheme.colors.icon.warning, + focusedLabelColor = TangemTheme.colors.text.primary1, + unfocusedLabelColor = TangemTheme.colors.text.secondary, + disabledLabelColor = TangemTheme.colors.text.disabled, + errorLabelColor = TangemTheme.colors.icon.warning, + placeholderColor = TangemTheme.colors.text.secondary, + disabledPlaceholderColor = TangemTheme.colors.text.disabled, + captionColor = TangemTheme.colors.text.tertiary, + disabledCaptionColor = TangemTheme.colors.text.disabled, + errorCaptionColor = TangemTheme.colors.icon.warning, + ) +} + +@Immutable +internal data class TangemTextFieldColors( + private val textColor: Color, + private val disabledTextColor: Color, + private val cursorColor: Color, + private val errorCursorColor: Color, + private val focusedIndicatorColor: Color, + private val unfocusedIndicatorColor: Color, + private val errorIndicatorColor: Color, + private val disabledIndicatorColor: Color, + private val leadingIconColor: Color, + private val disabledLeadingIconColor: Color, + private val errorLeadingIconColor: Color, + private val trailingIconColor: Color, + private val disabledTrailingIconColor: Color, + private val errorTrailingIconColor: Color, + private val backgroundColor: Color, + private val focusedLabelColor: Color, + private val unfocusedLabelColor: Color, + private val disabledLabelColor: Color, + private val errorLabelColor: Color, + private val placeholderColor: Color, + private val disabledPlaceholderColor: Color, + private val captionColor: Color, + private val disabledCaptionColor: Color, + private val errorCaptionColor: Color, +) : TextFieldColors { + + @Composable + override fun leadingIconColor(enabled: Boolean, isError: Boolean): State { + return rememberUpdatedState( + when { + !enabled -> disabledLeadingIconColor + isError -> errorLeadingIconColor + else -> leadingIconColor + }, + ) + } + + @Composable + override fun trailingIconColor(enabled: Boolean, isError: Boolean): State { + return rememberUpdatedState( + when { + !enabled -> disabledTrailingIconColor + isError -> errorTrailingIconColor + else -> trailingIconColor + }, + ) + } + + @Composable + override fun indicatorColor( + enabled: Boolean, + isError: Boolean, + interactionSource: InteractionSource, + ): State { + val focused by interactionSource.collectIsFocusedAsState() + + val targetValue = when { + !enabled -> disabledIndicatorColor + isError -> errorIndicatorColor + focused -> focusedIndicatorColor + else -> unfocusedIndicatorColor + } + return if (enabled) { + animateColorAsState(targetValue, tween(durationMillis = 120)) + } else { + rememberUpdatedState(targetValue) + } + } + + @Composable + override fun backgroundColor(enabled: Boolean): State { + return rememberUpdatedState(backgroundColor) + } + + @Composable + override fun placeholderColor(enabled: Boolean): State { + return rememberUpdatedState(if (enabled) placeholderColor else disabledPlaceholderColor) + } + + @Composable + override fun labelColor( + enabled: Boolean, + error: Boolean, + interactionSource: InteractionSource, + ): State { + val focused by interactionSource.collectIsFocusedAsState() + + val targetValue = when { + !enabled -> disabledLabelColor + error -> errorLabelColor + focused -> focusedLabelColor + else -> unfocusedLabelColor + } + return rememberUpdatedState(targetValue) + } + + @Composable + override fun textColor(enabled: Boolean): State { + return rememberUpdatedState(if (enabled) textColor else disabledTextColor) + } + + @Composable + override fun cursorColor(isError: Boolean): State { + return rememberUpdatedState(if (isError) errorCursorColor else cursorColor) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/addCustomToken/AddCustomTokenFragment.kt b/app/src/main/java/com/tangem/tap/features/tokens/addCustomToken/AddCustomTokenFragment.kt index 0c03a6869d..6cd4e7659a 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/addCustomToken/AddCustomTokenFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/addCustomToken/AddCustomTokenFragment.kt @@ -10,10 +10,10 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView -import com.google.accompanist.appcompattheme.AppCompatTheme +import com.tangem.core.analytics.Analytics +import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.features.addCustomToken.redux.AddCustomTokenState import com.tangem.domain.redux.domainStore -import com.tangem.core.analytics.Analytics import com.tangem.tap.common.analytics.events.ManageTokens import com.tangem.tap.common.compose.ClosePopupTrigger import com.tangem.tap.features.BaseStoreFragment @@ -57,7 +57,7 @@ class AddCustomTokenFragment : BaseStoreFragment(R.layout.view_compose_fragment) val closePopupTrigger = initClosingPopupTriggerEvent() view.findViewById(R.id.view_compose)?.setContent { - AppCompatTheme(requireContext()) { + TangemTheme { Box( modifier = Modifier .fillMaxSize(), diff --git a/app/src/main/java/com/tangem/tap/features/tokens/addCustomToken/compose/AddCustomTokenScreen.kt b/app/src/main/java/com/tangem/tap/features/tokens/addCustomToken/compose/AddCustomTokenScreen.kt index fe5f66f086..1d57e7472d 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/addCustomToken/compose/AddCustomTokenScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/addCustomToken/compose/AddCustomTokenScreen.kt @@ -6,23 +6,16 @@ import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.BottomSheetScaffold import androidx.compose.material.BottomSheetScaffoldState import androidx.compose.material.BottomSheetState import androidx.compose.material.BottomSheetValue import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ExtendedFloatingActionButton import androidx.compose.material.FabPosition -import androidx.compose.material.FloatingActionButtonDefaults -import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold import androidx.compose.material.Surface -import androidx.compose.material.Text -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Add import androidx.compose.material.rememberBottomSheetScaffoldState import androidx.compose.material.rememberScaffoldState import androidx.compose.runtime.Composable @@ -33,12 +26,14 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import com.tangem.core.ui.components.PrimaryButtonIconLeft import com.tangem.core.ui.components.keyboardAsState +import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.AddCustomTokenError import com.tangem.domain.common.form.DataField import com.tangem.domain.common.form.FieldId @@ -56,7 +51,6 @@ import com.tangem.domain.redux.domainStore import com.tangem.tap.common.compose.AddCustomTokenWarning import com.tangem.tap.common.compose.ClosePopupTrigger import com.tangem.tap.common.compose.ComposeDialogManager -import com.tangem.tap.common.compose.ToggledRippleTheme import com.tangem.tap.domain.moduleMessage.ModuleMessageConverter import com.tangem.tap.features.tokens.addCustomToken.compose.test.TestCase import com.tangem.tap.features.tokens.addCustomToken.compose.test.TestCasesList @@ -127,8 +121,12 @@ private fun ScreenContent( } }, floatingActionButtonPosition = FabPosition.Center, - ) { - Box(Modifier.fillMaxSize()) { + ) { paddings -> + Box( + modifier = Modifier + .padding(paddings) + .fillMaxSize(), + ) { LazyColumn( contentPadding = PaddingValues(bottom = 90.dp), ) { @@ -200,41 +198,15 @@ fun Warnings(warnings: List) { @Composable private fun AddButton(state: MutableState) { - AddCustomTokenFab( + PrimaryButtonIconLeft( modifier = Modifier - .widthIn(210.dp, 280.dp), - isEnabled = state.value.screenState.addButton.isEnabled, - ) { domainStore.dispatch(AddCustomTokenAction.OnAddCustomTokenClicked) } -} - -@Suppress("MagicNumber") -@Composable -private fun AddCustomTokenFab(modifier: Modifier = Modifier, isEnabled: Boolean = true, onClick: () -> Unit) { - val contentColor = Color.White - val backgroundColor = if (isEnabled) Color(0xFF1ACE80) else Color(0xFFB9E6D3) - val elevation = if (!isEnabled) { - FloatingActionButtonDefaults.elevation(0.dp, 0.dp) - } else { - FloatingActionButtonDefaults.elevation() - } - - ToggledRippleTheme(isEnabled) { - ExtendedFloatingActionButton( - modifier = modifier, - icon = { - Icon( - imageVector = Icons.Filled.Add, - tint = contentColor, - contentDescription = "Add", - ) - }, - text = { Text(text = stringResource(id = R.string.common_add)) }, - onClick = { if (isEnabled) onClick() }, - backgroundColor = backgroundColor, - contentColor = contentColor, - elevation = elevation, - ) - } + .padding(horizontal = TangemTheme.dimens.spacing16) + .fillMaxWidth(), + text = stringResource(id = R.string.common_add), + icon = painterResource(id = R.drawable.ic_plus_24), + enabled = state.value.screenState.addButton.isEnabled, + onClick = { domainStore.dispatch(AddCustomTokenAction.OnAddCustomTokenClicked) }, + ) } data class ScreenFieldData( diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/AddTokensFragment.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/AddTokensFragment.kt index 9f9288ea99..7c8c5b5f14 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/ui/AddTokensFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/AddTokensFragment.kt @@ -11,9 +11,9 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.transition.TransitionInflater import by.kirich1409.viewbindingdelegate.viewBinding -import com.google.accompanist.appcompattheme.AppCompatTheme import com.tangem.blockchain.common.Blockchain import com.tangem.core.analytics.Analytics +import com.tangem.core.ui.res.TangemTheme import com.tangem.tap.common.analytics.events.ManageTokens import com.tangem.tap.common.extensions.copyToClipboard import com.tangem.tap.common.extensions.dispatchNotification @@ -73,7 +73,7 @@ class AddTokensFragment : BaseFragment(R.layout.fragment_add_tokens), StoreSubsc } cvCurrencies.setContent { - AppCompatTheme { + TangemTheme { CurrenciesScreen( tokensState = tokensState, onSaveChanges = onSaveChanges, diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/CurrenciesScreen.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/CurrenciesScreen.kt index 371e343dda..94aab4a516 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/CurrenciesScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/CurrenciesScreen.kt @@ -9,12 +9,11 @@ import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.CircularProgressIndicator -import androidx.compose.material.ExtendedFloatingActionButton import androidx.compose.material.FabPosition import androidx.compose.material.Scaffold -import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue @@ -30,8 +29,10 @@ import androidx.compose.ui.unit.dp import com.tangem.blockchain.common.Blockchain import com.tangem.core.analytics.Analytics import com.tangem.core.ui.components.Keyboard +import com.tangem.core.ui.components.PrimaryButton import com.tangem.core.ui.components.SystemBarsEffect import com.tangem.core.ui.components.keyboardAsState +import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation import com.tangem.domain.common.extensions.fromNetworkId import com.tangem.tap.common.analytics.events.AnalyticsParam @@ -231,15 +232,12 @@ fun SaveChangesButton(keyboardState: Keyboard, onSaveChanges: () -> Unit) { 0 } - ExtendedFloatingActionButton( - text = { - Text( - text = stringResource(id = R.string.common_save_changes), - ) - }, + PrimaryButton( + modifier = Modifier + .padding(bottom = padding.dp) + .padding(horizontal = TangemTheme.dimens.spacing16) + .fillMaxWidth(), + text = stringResource(id = R.string.common_save_changes), onClick = onSaveChanges, - backgroundColor = colorResource(id = R.color.accent), - contentColor = Color.White, - modifier = Modifier.padding(bottom = padding.dp), ) } \ No newline at end of file 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 c3b2ef1f2c..5584176306 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 @@ -35,7 +35,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import com.tangem.core.ui.R import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemTypography /** * [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?node-id=97%3A103&t=TmfD6UBHPg9uYfev-4) @@ -305,7 +304,7 @@ private fun ButtonContent( } Text( text = text, - style = TangemTypography.button, + style = TangemTheme.typography.button, color = colors.contentColor(enabled = enabled).value, ) if (buttonIcon is TangemButtonIcon.Right) { diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/TextFields.kt b/core/ui/src/main/java/com/tangem/core/ui/components/TextFields.kt index a0459b8dc4..d047f34cc2 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/TextFields.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/TextFields.kt @@ -106,7 +106,7 @@ private fun TangemTextField( .height(IntrinsicSize.Min) .heightIn(size.toHeightDp()), value = value, - textStyle = TangemTypography.body1, + textStyle = TangemTheme.typography.body1, onValueChange = onValueChange, singleLine = singleLine, enabled = enabled, @@ -121,7 +121,7 @@ private fun TangemTextField( if (!label.isNullOrEmpty()) { Text( text = label, - style = TangemTypography.caption, + style = TangemTheme.typography.caption, color = colors.labelColor( enabled = enabled, error = isError, @@ -134,7 +134,7 @@ private fun TangemTextField( if (!placeholder.isNullOrEmpty()) { Text( text = placeholder, - style = TangemTypography.body1, + style = TangemTheme.typography.body1, color = colors.placeholderColor(enabled = enabled).value, ) }