diff --git a/example/src/main/kotlin/com/processout/example/ProcessOutExampleApplication.kt b/example/src/main/kotlin/com/processout/example/ProcessOutExampleApplication.kt index 5a5a4e4e4..63a5b4758 100644 --- a/example/src/main/kotlin/com/processout/example/ProcessOutExampleApplication.kt +++ b/example/src/main/kotlin/com/processout/example/ProcessOutExampleApplication.kt @@ -14,7 +14,8 @@ class ProcessOutExampleApplication : Application() { ProcessOutConfiguration( application = this, projectId = BuildConfig.PROJECT_ID, - debug = true + debug = true, + enableTelemetry = false ).apply { privateKey = BuildConfig.PROJECT_KEY } ) } diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POActionsContainer.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POActionsContainer.kt index 11fe61024..6383c6e85 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POActionsContainer.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POActionsContainer.kt @@ -17,7 +17,7 @@ import com.processout.sdk.ui.core.state.POActionState import com.processout.sdk.ui.core.state.POImmutableList import com.processout.sdk.ui.core.style.POActionsContainerStyle import com.processout.sdk.ui.core.style.POAxis -import com.processout.sdk.ui.core.theme.ProcessOutTheme +import com.processout.sdk.ui.core.theme.ProcessOutTheme.colors import com.processout.sdk.ui.core.theme.ProcessOutTheme.dimensions import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing @@ -127,26 +127,13 @@ object POActionsContainer { ) val default: Style - @Composable get() = with(ProcessOutTheme) { - Style( - primary = POButton.primary, - secondary = POButton.secondary, - dividerColor = colors.border.border4, - backgroundColor = colors.surface.default, - axis = POAxis.Vertical - ) - } - - val default2: Style - @Composable get() = with(ProcessOutTheme) { - Style( - primary = POButton.primary2, - secondary = POButton.secondary2, - dividerColor = colors.border.border4, - backgroundColor = colors.surface.default, - axis = POAxis.Vertical - ) - } + @Composable get() = Style( + primary = POButton.primary, + secondary = POButton.secondary, + dividerColor = colors.border.border4, + backgroundColor = colors.surface.default, + axis = POAxis.Vertical + ) @Composable fun custom(style: POActionsContainerStyle) = with(style) { diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POButton.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POButton.kt index 498e7b8a2..bed20d62e 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POButton.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POButton.kt @@ -37,9 +37,11 @@ import com.processout.sdk.ui.core.state.POActionState import com.processout.sdk.ui.core.style.POButtonDefaults import com.processout.sdk.ui.core.style.POButtonStateStyle import com.processout.sdk.ui.core.style.POButtonStyle -import com.processout.sdk.ui.core.theme.ProcessOutTheme +import com.processout.sdk.ui.core.theme.ProcessOutTheme.colors import com.processout.sdk.ui.core.theme.ProcessOutTheme.dimensions +import com.processout.sdk.ui.core.theme.ProcessOutTheme.shapes import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing +import com.processout.sdk.ui.core.theme.ProcessOutTheme.typography /** @suppress */ @ProcessOutInternalApi @@ -111,7 +113,7 @@ fun POButton( contentDescription = null, modifier = Modifier .conditional(text.isNotBlank()) { - padding(end = spacing.small) + padding(end = spacing.space8) } .requiredSize(iconSize), colorFilter = iconColorFilter @@ -222,164 +224,94 @@ object POButton { } val primary: Style - @Composable get() = with(ProcessOutTheme) { - Style( - normal = StateStyle( - text = POText.Style( - color = colors.text.inverse, - textStyle = typography.button - ), - shape = shapes.roundedCornersSmall, - border = POBorderStroke(width = 0.dp, color = Color.Transparent), - backgroundColor = colors.button.primaryBackgroundDefault, - elevation = 0.dp + @Composable get() = Style( + normal = StateStyle( + text = POText.Style( + color = colors.text.inverse, + textStyle = typography.s15(FontWeight.Medium) ), - disabled = StateStyle( - text = POText.Style( - color = colors.text.onButtonDisabled, - textStyle = typography.button - ), - shape = shapes.roundedCornersSmall, - border = POBorderStroke(width = 0.dp, color = Color.Transparent), - backgroundColor = colors.button.primaryBackgroundDisabled, - elevation = 0.dp + shape = shapes.roundedCorners6, + border = POBorderStroke(width = 0.dp, color = Color.Transparent), + backgroundColor = colors.button.primaryBackgroundDefault, + elevation = 0.dp + ), + disabled = StateStyle( + text = POText.Style( + color = colors.text.onButtonDisabled, + textStyle = typography.s15(FontWeight.Medium) ), - highlighted = HighlightedStyle( - textColor = colors.text.inverse, - borderColor = Color.Transparent, - backgroundColor = colors.button.primaryBackgroundPressed - ), - progressIndicatorColor = colors.text.inverse - ) - } - - val primary2: Style - @Composable get() = with(ProcessOutTheme) { - Style( - normal = StateStyle( - text = POText.Style( - color = colors.text.inverse, - textStyle = typography.s15(FontWeight.Medium) - ), - shape = shapes.roundedCorners6, - border = POBorderStroke(width = 0.dp, color = Color.Transparent), - backgroundColor = colors.button.primaryBackgroundDefault, - elevation = 0.dp - ), - disabled = StateStyle( - text = POText.Style( - color = colors.text.onButtonDisabled, - textStyle = typography.s15(FontWeight.Medium) - ), - shape = shapes.roundedCorners6, - border = POBorderStroke(width = 0.dp, color = Color.Transparent), - backgroundColor = colors.button.primaryBackgroundDisabled, - elevation = 0.dp - ), - highlighted = HighlightedStyle( - textColor = colors.text.inverse, - borderColor = Color.Transparent, - backgroundColor = colors.button.primaryBackgroundPressed - ), - progressIndicatorColor = colors.text.inverse - ) - } + shape = shapes.roundedCorners6, + border = POBorderStroke(width = 0.dp, color = Color.Transparent), + backgroundColor = colors.button.primaryBackgroundDisabled, + elevation = 0.dp + ), + highlighted = HighlightedStyle( + textColor = colors.text.inverse, + borderColor = Color.Transparent, + backgroundColor = colors.button.primaryBackgroundPressed + ), + progressIndicatorColor = colors.text.inverse + ) val secondary: Style - @Composable get() = with(ProcessOutTheme) { - Style( - normal = StateStyle( - text = POText.Style( - color = colors.text.primary, - textStyle = typography.button - ), - shape = shapes.roundedCornersSmall, - border = POBorderStroke(width = 0.dp, color = Color.Transparent), - backgroundColor = colors.button.secondaryBackgroundDefault, - elevation = 0.dp - ), - disabled = StateStyle( - text = POText.Style( - color = colors.text.onButtonDisabled, - textStyle = typography.button - ), - shape = shapes.roundedCornersSmall, - border = POBorderStroke(width = 0.dp, color = Color.Transparent), - backgroundColor = colors.button.secondaryBackgroundDisabled, - elevation = 0.dp - ), - highlighted = HighlightedStyle( - textColor = colors.text.primary, - borderColor = Color.Transparent, - backgroundColor = colors.button.secondaryBackgroundPressed + @Composable get() = Style( + normal = StateStyle( + text = POText.Style( + color = colors.text.primary, + textStyle = typography.s15(FontWeight.Medium) ), - progressIndicatorColor = colors.text.primary - ) - } - - val secondary2: Style - @Composable get() = with(ProcessOutTheme) { - Style( - normal = StateStyle( - text = POText.Style( - color = colors.text.primary, - textStyle = typography.s15(FontWeight.Medium) - ), - shape = shapes.roundedCorners6, - border = POBorderStroke(width = 0.dp, color = Color.Transparent), - backgroundColor = colors.button.secondaryBackgroundDefault, - elevation = 0.dp + shape = shapes.roundedCorners6, + border = POBorderStroke(width = 0.dp, color = Color.Transparent), + backgroundColor = colors.button.secondaryBackgroundDefault, + elevation = 0.dp + ), + disabled = StateStyle( + text = POText.Style( + color = colors.text.onButtonDisabled, + textStyle = typography.s15(FontWeight.Medium) ), - disabled = StateStyle( - text = POText.Style( - color = colors.text.onButtonDisabled, - textStyle = typography.s15(FontWeight.Medium) - ), - shape = shapes.roundedCorners6, - border = POBorderStroke(width = 0.dp, color = Color.Transparent), - backgroundColor = colors.button.secondaryBackgroundDisabled, - elevation = 0.dp - ), - highlighted = HighlightedStyle( - textColor = colors.text.primary, - borderColor = Color.Transparent, - backgroundColor = colors.button.secondaryBackgroundPressed - ), - progressIndicatorColor = colors.text.primary - ) - } + shape = shapes.roundedCorners6, + border = POBorderStroke(width = 0.dp, color = Color.Transparent), + backgroundColor = colors.button.secondaryBackgroundDisabled, + elevation = 0.dp + ), + highlighted = HighlightedStyle( + textColor = colors.text.primary, + borderColor = Color.Transparent, + backgroundColor = colors.button.secondaryBackgroundPressed + ), + progressIndicatorColor = colors.text.primary + ) val ghost: Style - @Composable get() = with(ProcessOutTheme) { - Style( - normal = StateStyle( - text = POText.Style( - color = colors.text.primary, - textStyle = typography.s15(FontWeight.Medium) - ), - shape = shapes.roundedCorners6, - border = POBorderStroke(width = 0.dp, color = Color.Transparent), - backgroundColor = Color.Transparent, - elevation = 0.dp - ), - disabled = StateStyle( - text = POText.Style( - color = colors.text.onButtonDisabled, - textStyle = typography.s15(FontWeight.Medium) - ), - shape = shapes.roundedCorners6, - border = POBorderStroke(width = 0.dp, color = Color.Transparent), - backgroundColor = colors.button.ghostBackgroundDisabled, - elevation = 0.dp + @Composable get() = Style( + normal = StateStyle( + text = POText.Style( + color = colors.text.primary, + textStyle = typography.s15(FontWeight.Medium) ), - highlighted = HighlightedStyle( - textColor = colors.text.primary, - borderColor = Color.Transparent, - backgroundColor = colors.button.ghostBackgroundPressed + shape = shapes.roundedCorners6, + border = POBorderStroke(width = 0.dp, color = Color.Transparent), + backgroundColor = Color.Transparent, + elevation = 0.dp + ), + disabled = StateStyle( + text = POText.Style( + color = colors.text.onButtonDisabled, + textStyle = typography.s15(FontWeight.Medium) ), - progressIndicatorColor = colors.text.primary - ) - } + shape = shapes.roundedCorners6, + border = POBorderStroke(width = 0.dp, color = Color.Transparent), + backgroundColor = colors.button.ghostBackgroundDisabled, + elevation = 0.dp + ), + highlighted = HighlightedStyle( + textColor = colors.text.primary, + borderColor = Color.Transparent, + backgroundColor = colors.button.ghostBackgroundPressed + ), + progressIndicatorColor = colors.text.primary + ) val ghostEqualPadding: Style @Composable get() = ghost.let { diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POCopyButton.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POCopyButton.kt index 42169ef54..c02c9bd4b 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POCopyButton.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POCopyButton.kt @@ -76,7 +76,7 @@ fun POCopyButton( object POCopyButton { val default: POButton.Style - @Composable get() = POButton.secondary2.let { + @Composable get() = POButton.secondary.let { it.copy( normal = it.normal.copy( text = it.normal.text.copy( diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/PODialog.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/PODialog.kt index 35f737eea..36b692c7b 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/PODialog.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/PODialog.kt @@ -84,8 +84,8 @@ fun PODialog( Surface( modifier = Modifier .fillMaxWidth() - .padding(spacing.extraLarge), - shape = shapes.roundedCornersLarge, + .padding(spacing.space20), + shape = shapes.roundedCorners16, color = style.backgroundColor, contentColor = Color.Unspecified, shadowElevation = 3.dp @@ -93,7 +93,7 @@ fun PODialog( Column( modifier = Modifier .fillMaxWidth() - .padding(spacing.extraLarge) + .padding(spacing.space20) ) { POText( text = title, @@ -103,7 +103,7 @@ fun PODialog( if (!message.isNullOrBlank()) { POText( text = message, - modifier = Modifier.padding(top = spacing.large), + modifier = Modifier.padding(top = spacing.space16), color = style.message.color, style = style.message.textStyle ) @@ -111,9 +111,9 @@ fun PODialog( Row( modifier = Modifier .fillMaxWidth() - .padding(top = spacing.extraLarge), + .padding(top = spacing.space20), horizontalArrangement = Arrangement.spacedBy( - space = spacing.small, + space = spacing.space8, alignment = Alignment.End ), verticalAlignment = Alignment.CenterVertically diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/PODragHandle.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/PODragHandle.kt index 913249040..845ba92ba 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/PODragHandle.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/PODragHandle.kt @@ -26,7 +26,7 @@ fun PODragHandle( ) .background( color = color, - shape = shapes.roundedCornersSmall + shape = shapes.roundedCorners4 ) ) } diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POGroupedContent.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POGroupedContent.kt index 0fb21f86d..10c080fe8 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POGroupedContent.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POGroupedContent.kt @@ -91,7 +91,7 @@ object POGroupedContent { textStyle = typography.s16(FontWeight.Medium) ), shape = shapes.roundedCorners6, - border = POBorderStroke(width = 1.5.dp, color = colors.input.borderDefault2), + border = POBorderStroke(width = 1.5.dp, color = colors.input.borderDefault), dividerColor = colors.border.border1, backgroundColor = colors.surface.default ) diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POHeader.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POHeader.kt index 2fbc2df6b..eee46aeba 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POHeader.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POHeader.kt @@ -10,11 +10,13 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi import com.processout.sdk.ui.core.extension.conditional import com.processout.sdk.ui.core.theme.ProcessOutTheme.colors import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing +import com.processout.sdk.ui.core.theme.ProcessOutTheme.typography /** @suppress */ @ProcessOutInternalApi @@ -22,7 +24,10 @@ import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing fun POHeader( title: String?, modifier: Modifier = Modifier, - style: POText.Style = POText.title, + style: POText.Style = POText.Style( + color = colors.text.primary, + textStyle = typography.s20(FontWeight.Medium) + ), dividerColor: Color = colors.border.border4, dragHandleColor: Color = colors.icon.disabled, withDragHandle: Boolean = true, @@ -33,7 +38,7 @@ fun POHeader( if (withDragHandle) { PODragHandle( modifier = Modifier - .padding(top = spacing.medium) + .padding(top = spacing.space12) .align(alignment = Alignment.TopCenter), color = dragHandleColor ) @@ -45,7 +50,7 @@ fun POHeader( ) { Column( modifier = Modifier.conditional(withDragHandle) { - padding(top = spacing.small) + padding(top = spacing.space8) } ) { Row( @@ -61,7 +66,7 @@ fun POHeader( text = currentTitle, modifier = Modifier .weight(1f, fill = false) - .padding(spacing.extraLarge), + .padding(spacing.space20), color = style.color, style = style.textStyle ) diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POMessageBox.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POMessageBox.kt index 90853fb12..5d0e700e9 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POMessageBox.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POMessageBox.kt @@ -85,19 +85,6 @@ object POMessageBox { ) val error: Style - @Composable get() = Style( - textWithIcon = POTextWithIcon.default.copy( - iconResId = R.drawable.po_icon_warning_diamond - ), - shape = shapes.roundedCornersSmall, - border = POBorderStroke( - width = 1.dp, - color = colors.input.borderError - ), - backgroundColor = colors.surface.error - ) - - val error2: Style @Composable get() { val text = Style( color = colors.text.onTipError, @@ -112,7 +99,7 @@ object POMessageBox { shape = shapes.roundedCorners8, border = POBorderStroke( width = 1.dp, - color = colors.input.borderDefault2 + color = colors.input.borderDefault ), backgroundColor = colors.surface.toastError ) diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POText.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POText.kt index e5644c1c2..12a385c05 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POText.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POText.kt @@ -11,10 +11,10 @@ import androidx.compose.ui.res.colorResource import androidx.compose.ui.text.TextLayoutResult import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi @@ -30,7 +30,7 @@ fun POText( text: String, modifier: Modifier = Modifier, color: Color = Color.Unspecified, - style: TextStyle = ProcessOutTheme.typography.body1, + style: TextStyle = ProcessOutTheme.typography.s16(FontWeight.Medium), fontStyle: FontStyle? = null, textAlign: TextAlign? = null, onTextLayout: (TextLayoutResult) -> Unit = {}, @@ -62,42 +62,6 @@ object POText { val textStyle: TextStyle ) - val title: Style - @Composable get() = Style( - color = ProcessOutTheme.colors.text.primary, - textStyle = ProcessOutTheme.typography.title - ) - - val subheading: Style - @Composable get() = Style( - color = ProcessOutTheme.colors.text.primary, - textStyle = ProcessOutTheme.typography.subheading - ) - - val body1: Style - @Composable get() = Style( - color = ProcessOutTheme.colors.text.primary, - textStyle = ProcessOutTheme.typography.body1 - ) - - val body2: Style - @Composable get() = Style( - color = ProcessOutTheme.colors.text.primary, - textStyle = ProcessOutTheme.typography.body2 - ) - - val label1: Style - @Composable get() = Style( - color = ProcessOutTheme.colors.text.primary, - textStyle = ProcessOutTheme.typography.label1 - ) - - val errorLabel: Style - @Composable get() = Style( - color = ProcessOutTheme.colors.text.error, - textStyle = ProcessOutTheme.typography.label2 - ) - @Composable fun custom(style: POTextStyle) = Style( color = colorResource(id = style.colorResId), @@ -127,9 +91,3 @@ object POText { } } } - -@Composable -@Preview(showBackground = true) -private fun POTextPreview() { - POText(text = "ProcessOut Payment") -} diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POTextAutoSize.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POTextAutoSize.kt index 699e11efe..ee7af2c52 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POTextAutoSize.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POTextAutoSize.kt @@ -6,6 +6,7 @@ import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi import com.processout.sdk.ui.core.theme.ProcessOutTheme @@ -17,7 +18,7 @@ fun POTextAutoSize( text: String, modifier: Modifier = Modifier, color: Color = Color.Unspecified, - style: TextStyle = ProcessOutTheme.typography.body1, + style: TextStyle = ProcessOutTheme.typography.s16(FontWeight.Medium), fontStyle: FontStyle? = null, textAlign: TextAlign? = null, step: Float = 0.01f diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POTextWithIcon.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POTextWithIcon.kt index 92b5b5cc6..f353e5359 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POTextWithIcon.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/POTextWithIcon.kt @@ -89,7 +89,7 @@ object POTextWithIcon { @Composable get() { val text = Style( color = colors.text.primary, - textStyle = typography.body2 + textStyle = typography.s14() ) return Style( text = text, diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/LabeledFieldLayout.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/LabeledFieldLayout.kt deleted file mode 100644 index af8309e91..000000000 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/LabeledFieldLayout.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.processout.sdk.ui.core.component.field - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextAlign -import com.processout.sdk.ui.core.component.POExpandableText -import com.processout.sdk.ui.core.component.POText -import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing - -@Composable -internal fun LabeledFieldLayout( - title: String?, - description: String?, - style: POFieldLabels.Style = POFieldLabels.default, - horizontalAlignment: Alignment.Horizontal = Alignment.Start, - content: @Composable () -> Unit -) { - Column( - horizontalAlignment = horizontalAlignment - ) { - if (title != null) { - POText( - text = title, - modifier = Modifier.padding(bottom = spacing.small), - color = style.title.color, - style = style.title.textStyle, - textAlign = textAlign(horizontalAlignment) - ) - } - content() - POExpandableText( - text = description, - modifier = Modifier - .fillMaxWidth() - .padding(top = spacing.small), - style = style.description, - textAlign = textAlign(horizontalAlignment) - ) - } -} - -private fun textAlign( - horizontalAlignment: Alignment.Horizontal -): TextAlign = when (horizontalAlignment) { - Alignment.Start -> TextAlign.Start - Alignment.CenterHorizontally -> TextAlign.Center - Alignment.End -> TextAlign.End - else -> TextAlign.Unspecified -} diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/POField.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/POField.kt index 4e4daf2c8..e58e6d69e 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/POField.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/POField.kt @@ -33,8 +33,8 @@ import com.processout.sdk.ui.core.component.POText import com.processout.sdk.ui.core.extension.conditional import com.processout.sdk.ui.core.style.POFieldStateStyle import com.processout.sdk.ui.core.style.POFieldStyle -import com.processout.sdk.ui.core.theme.ProcessOutTheme import com.processout.sdk.ui.core.theme.ProcessOutTheme.colors +import com.processout.sdk.ui.core.theme.ProcessOutTheme.shapes import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing import com.processout.sdk.ui.core.theme.ProcessOutTheme.typography @@ -62,97 +62,56 @@ object POField { ) val default: Style - @Composable get() = with(ProcessOutTheme) { - Style( - normal = StateStyle( - text = POText.body2, - label = POText.label1, - placeholderTextColor = colors.text.muted, - backgroundColor = colors.input.backgroundDefault, - controlsTintColor = colors.text.primary, - dropdownRippleColor = colors.text.muted, - shape = shapes.roundedCornersSmall, - border = POBorderStroke(width = 1.dp, color = colors.input.borderDefault) + @Composable get() = Style( + normal = StateStyle( + text = POText.Style( + color = colors.text.primary, + textStyle = typography.s15(FontWeight.Medium) ), - error = StateStyle( - text = POText.body2, - label = POText.Style( - color = colors.text.error, - textStyle = typography.label1 - ), - placeholderTextColor = colors.text.muted, - backgroundColor = colors.input.backgroundDefault, - controlsTintColor = colors.text.primary, - dropdownRippleColor = colors.text.muted, - shape = shapes.roundedCornersSmall, - border = POBorderStroke(width = 1.dp, color = colors.input.borderError) + label = POText.Style( + color = colors.text.placeholder, + textStyle = typography.s15(FontWeight.Medium) ), - focused = StateStyle( - text = POText.body2, - label = POText.label1, - placeholderTextColor = colors.text.muted, - backgroundColor = colors.input.backgroundDefault, - controlsTintColor = colors.text.primary, - dropdownRippleColor = colors.text.muted, - shape = shapes.roundedCornersSmall, - border = POBorderStroke(width = 1.dp, color = colors.input.borderFocused) - ) - ) - } - - val default2: Style - @Composable get() = with(ProcessOutTheme) { - Style( - normal = StateStyle( - text = POText.Style( - color = colors.text.primary, - textStyle = typography.s15(FontWeight.Medium) - ), - label = POText.Style( - color = colors.text.placeholder, - textStyle = typography.s15(FontWeight.Medium) - ), - placeholderTextColor = colors.text.placeholder, - backgroundColor = colors.input.backgroundDefault, - controlsTintColor = colors.text.primary, - dropdownRippleColor = colors.text.muted, - shape = shapes.roundedCorners6, - border = POBorderStroke(width = 1.5.dp, color = colors.input.borderDefault2) + placeholderTextColor = colors.text.placeholder, + backgroundColor = colors.input.backgroundDefault, + controlsTintColor = colors.text.primary, + dropdownRippleColor = colors.text.muted, + shape = shapes.roundedCorners6, + border = POBorderStroke(width = 1.5.dp, color = colors.input.borderDefault) + ), + error = StateStyle( + text = POText.Style( + color = colors.text.primary, + textStyle = typography.s15(FontWeight.Medium) ), - error = StateStyle( - text = POText.Style( - color = colors.text.primary, - textStyle = typography.s15(FontWeight.Medium) - ), - label = POText.Style( - color = colors.text.error, - textStyle = typography.s15(FontWeight.Medium) - ), - placeholderTextColor = colors.text.placeholder, - backgroundColor = colors.input.backgroundDefault, - controlsTintColor = colors.text.primary, - dropdownRippleColor = colors.text.muted, - shape = shapes.roundedCorners6, - border = POBorderStroke(width = 1.5.dp, color = colors.input.borderError) + label = POText.Style( + color = colors.text.error, + textStyle = typography.s15(FontWeight.Medium) ), - focused = StateStyle( - text = POText.Style( - color = colors.text.primary, - textStyle = typography.s15(FontWeight.Medium) - ), - label = POText.Style( - color = colors.text.placeholder, - textStyle = typography.s15(FontWeight.Medium) - ), - placeholderTextColor = colors.text.placeholder, - backgroundColor = colors.input.backgroundDefault, - controlsTintColor = colors.text.primary, - dropdownRippleColor = colors.text.muted, - shape = shapes.roundedCorners6, - border = POBorderStroke(width = 1.5.dp, color = colors.text.primary) - ) + placeholderTextColor = colors.text.placeholder, + backgroundColor = colors.input.backgroundDefault, + controlsTintColor = colors.text.primary, + dropdownRippleColor = colors.text.muted, + shape = shapes.roundedCorners6, + border = POBorderStroke(width = 1.5.dp, color = colors.input.borderError) + ), + focused = StateStyle( + text = POText.Style( + color = colors.text.primary, + textStyle = typography.s15(FontWeight.Medium) + ), + label = POText.Style( + color = colors.text.placeholder, + textStyle = typography.s15(FontWeight.Medium) + ), + placeholderTextColor = colors.text.placeholder, + backgroundColor = colors.input.backgroundDefault, + controlsTintColor = colors.text.primary, + dropdownRippleColor = colors.text.muted, + shape = shapes.roundedCorners6, + border = POBorderStroke(width = 1.5.dp, color = colors.text.primary) ) - } + ) @Composable fun custom(style: POFieldStyle): Style { @@ -208,12 +167,6 @@ object POField { ) val contentPadding: PaddingValues - @Composable get() = PaddingValues( - horizontal = spacing.large, - vertical = spacing.medium - ) - - val contentPadding2: PaddingValues @Composable get() = PaddingValues( horizontal = spacing.space12, vertical = spacing.space6 diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/POFieldLabels.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/POFieldLabels.kt deleted file mode 100644 index 18e4955b3..000000000 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/POFieldLabels.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.processout.sdk.ui.core.component.field - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Immutable -import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi -import com.processout.sdk.ui.core.component.POText - -/** @suppress */ -@ProcessOutInternalApi -object POFieldLabels { - - @Immutable - data class Style( - val title: POText.Style, - val description: POText.Style - ) - - val default: Style - @Composable get() = Style( - title = POText.label1, - description = POText.errorLabel - ) -} diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/checkbox/POCheckbox.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/checkbox/POCheckbox.kt index ad64da76e..f7db9b01f 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/checkbox/POCheckbox.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/checkbox/POCheckbox.kt @@ -126,49 +126,6 @@ object POCheckbox { ) val default: Style - @Composable get() = Style( - normal = StateStyle( - checkmark = CheckmarkStyle( - color = colors.surface.default, - borderColor = colors.input.borderDefault, - backgroundColor = colors.surface.default - ), - text = POText.label1, - rippleColor = colors.surface.darkoutRipple - ), - selected = StateStyle( - checkmark = CheckmarkStyle( - color = colors.surface.default, - borderColor = colors.button.primaryBackgroundDefault, - backgroundColor = colors.button.primaryBackgroundDefault - ), - text = POText.label1, - rippleColor = colors.surface.darkoutRipple - ), - error = StateStyle( - checkmark = CheckmarkStyle( - color = colors.input.borderError, - borderColor = colors.input.borderError, - backgroundColor = colors.surface.default - ), - text = POText.label1, - rippleColor = colors.surface.darkoutRipple - ), - disabled = StateStyle( - checkmark = CheckmarkStyle( - color = colors.input.borderDisabled, - borderColor = colors.input.borderDisabled, - backgroundColor = colors.input.backgroundDisabled - ), - text = POText.Style( - color = colors.text.disabled, - textStyle = typography.label1 - ), - rippleColor = null - ) - ) - - val default2: Style @Composable get() = Style( normal = StateStyle( checkmark = CheckmarkStyle( diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/checkbox/POCheckboxField.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/checkbox/POCheckboxField.kt index 01f5227d6..432dbfc97 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/checkbox/POCheckboxField.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/checkbox/POCheckboxField.kt @@ -18,8 +18,8 @@ fun POCheckboxField( checked: Boolean, onCheckedChange: (Boolean) -> Unit, modifier: Modifier = Modifier, - checkboxStyle: POCheckbox.Style = POCheckbox.default2, - descriptionStyle: POMessageBox.Style = POMessageBox.error2, + checkboxStyle: POCheckbox.Style = POCheckbox.default, + descriptionStyle: POMessageBox.Style = POMessageBox.error, enabled: Boolean = true, isError: Boolean = false, description: String? = null, diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/code/POCodeField.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/code/POCodeField.kt index b6a20a416..0bf05bc39 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/code/POCodeField.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/code/POCodeField.kt @@ -25,9 +25,11 @@ import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import androidx.lifecycle.Lifecycle import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi +import com.processout.sdk.ui.core.component.POMessageBox import com.processout.sdk.ui.core.component.PORequestFocus import com.processout.sdk.ui.core.component.POText import com.processout.sdk.ui.core.component.field.POField +import com.processout.sdk.ui.core.component.field.POField.stateStyle import com.processout.sdk.ui.core.component.field.code.POCodeField.align import com.processout.sdk.ui.core.component.field.code.POCodeField.rememberTextFieldWidth import com.processout.sdk.ui.core.component.field.code.POCodeField.validLength @@ -35,7 +37,6 @@ import com.processout.sdk.ui.core.component.field.text.POTextField import com.processout.sdk.ui.core.component.texttoolbar.ProcessOutTextToolbar import com.processout.sdk.ui.core.state.POInputFilter import com.processout.sdk.ui.core.theme.ProcessOutTheme.colors -import com.processout.sdk.ui.core.theme.ProcessOutTheme.dimensions import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing import com.processout.sdk.ui.core.theme.ProcessOutTheme.typography @@ -46,9 +47,12 @@ fun POCodeField( value: TextFieldValue, onValueChange: (TextFieldValue) -> Unit, modifier: Modifier = Modifier, - style: POField.Style = POCodeField.default, + textFieldModifier: Modifier = Modifier, + fieldStyle: POField.Style = POCodeField.default, + descriptionStyle: POMessageBox.Style = POMessageBox.error, length: Int = POCodeField.LengthMax, - horizontalAlignment: Alignment.Horizontal = Alignment.CenterHorizontally, + label: String? = null, + description: String? = null, enabled: Boolean = true, isError: Boolean = false, isFocused: Boolean = false, @@ -57,142 +61,188 @@ fun POCodeField( keyboardOptions: KeyboardOptions = KeyboardOptions.Default, keyboardActions: KeyboardActions = KeyboardActions.Default ) { - var rowWidthPx by remember { mutableIntStateOf(0) } - val horizontalSpace = spacing.small - CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) { + Column(modifier = modifier) { + if (!label.isNullOrBlank()) { + val fieldStateStyle = fieldStyle.stateStyle( + isError = isError, + isFocused = isFocused + ) + POText( + text = label, + modifier = Modifier.padding(bottom = spacing.space12), + color = fieldStateStyle.label.color, + style = fieldStateStyle.label.textStyle + ) + } + Code( + value = value, + onValueChange = onValueChange, + style = fieldStyle, + length = length, + enabled = enabled, + isError = isError, + isFocused = isFocused, + lifecycleEvent = lifecycleEvent, + inputFilter = inputFilter, + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions, + modifier = textFieldModifier + ) + POMessageBox( + text = description, + modifier = Modifier.padding(top = spacing.space12), + style = descriptionStyle + ) + } +} + +@Composable +private fun Code( + value: TextFieldValue, + onValueChange: (TextFieldValue) -> Unit, + style: POField.Style, + length: Int, + enabled: Boolean, + isError: Boolean, + isFocused: Boolean, + lifecycleEvent: Lifecycle.Event?, + inputFilter: POInputFilter?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + modifier: Modifier = Modifier +) { + val validLength = remember(length) { validLength(length) } + var values by remember(validLength) { mutableStateOf(values(value.text, validLength, inputFilter)) } + var focusedIndex by remember(validLength) { mutableIntStateOf(values.focusedIndex()) } + val clipboardManager = LocalClipboardManager.current + CompositionLocalProvider( + LocalLayoutDirection provides LayoutDirection.Ltr, + LocalTextToolbar provides ProcessOutTextToolbar( + view = LocalView.current, + onPasteRequested = { + if (clipboardManager.hasText()) { + val pastedValues = values( + text = clipboardManager.getText()?.text ?: String(), + length = validLength, + inputFilter = inputFilter + ) + if (!pastedValues.all { it.text.isEmpty() }) { + values = pastedValues + focusedIndex = values.focusedIndex() + onValueChange(values.codeValue()) + } + } + }, + hideUnspecifiedActions = true + ) + ) { + var rowWidthPx by remember { mutableIntStateOf(0) } + val horizontalSpace = spacing.space8 Row( modifier = Modifier .focusGroup() .fillMaxWidth() .onGloballyPositioned { rowWidthPx = it.size.width }, - horizontalArrangement = Arrangement.spacedBy( - space = horizontalSpace, - alignment = horizontalAlignment - ), + horizontalArrangement = Arrangement.spacedBy(horizontalSpace), verticalAlignment = Alignment.CenterVertically ) { - val validLength = remember(length) { validLength(length) } - var values by remember(validLength) { mutableStateOf(values(value.text, validLength, inputFilter)) } - var focusedIndex by remember(validLength) { mutableIntStateOf(values.focusedIndex()) } - val clipboardManager = LocalClipboardManager.current - CompositionLocalProvider( - LocalTextToolbar provides ProcessOutTextToolbar( - view = LocalView.current, - onPasteRequested = { - if (clipboardManager.hasText()) { - val pastedValues = values( - text = clipboardManager.getText()?.text ?: String(), - length = validLength, - inputFilter = inputFilter - ) - if (!pastedValues.all { it.text.isEmpty() }) { - values = pastedValues - focusedIndex = values.focusedIndex() - onValueChange(values.codeValue()) + val focusManager = LocalFocusManager.current + for (textFieldIndex in values.indices) { + val focusRequester = remember { FocusRequester() } + POTextField( + value = values[textFieldIndex], + onValueChange = { updatedValue -> + if (updatedValue.selection.length == 0) { + val currentValue = values[textFieldIndex] + val updatedFilteredValue = inputFilter?.filter(updatedValue) ?: updatedValue + values = values.mapIndexed { index, textFieldValue -> + if (index == textFieldIndex) { + val updatedText = updatedFilteredValue.text.firstOrNull()?.toString() ?: String() + val isTextChanged = textFieldValue.text != updatedText + TextFieldValue( + text = updatedText, + selection = if (isTextChanged) { + TextRange(updatedText.length) + } else { + updatedFilteredValue.selection + } + ) + } else { + textFieldValue.copy(selection = TextRange.Zero) + } } - } - }, - hideUnspecifiedActions = true - ) - ) { - val focusManager = LocalFocusManager.current - for (textFieldIndex in values.indices) { - val focusRequester = remember { FocusRequester() } - POTextField( - value = values[textFieldIndex], - onValueChange = { updatedValue -> - if (updatedValue.selection.length == 0) { - val currentValue = values[textFieldIndex] - val updatedFilteredValue = inputFilter?.filter(updatedValue) ?: updatedValue + if (textFieldIndex != values.lastIndex && + updatedFilteredValue.text.length == 2 && + updatedFilteredValue.selection.start == 2 + ) { + val nextText = updatedFilteredValue.text.last().toString() values = values.mapIndexed { index, textFieldValue -> - if (index == textFieldIndex) { - val updatedText = updatedFilteredValue.text.firstOrNull()?.toString() ?: String() - val isTextChanged = textFieldValue.text != updatedText + if (index == textFieldIndex + 1) { TextFieldValue( - text = updatedText, - selection = if (isTextChanged) { - TextRange(updatedText.length) - } else { - updatedFilteredValue.selection - } + text = nextText, + selection = TextRange(nextText.length) ) } else { textFieldValue.copy(selection = TextRange.Zero) } } - if (textFieldIndex != values.lastIndex && - updatedFilteredValue.text.length == 2 && - updatedFilteredValue.selection.start == 2 - ) { - val nextText = updatedFilteredValue.text.last().toString() - values = values.mapIndexed { index, textFieldValue -> - if (index == textFieldIndex + 1) { - TextFieldValue( - text = nextText, - selection = TextRange(nextText.length) - ) - } else { - textFieldValue.copy(selection = TextRange.Zero) - } - } - } - val isSelectionChangedOnly = currentValue.text == updatedFilteredValue.text && - currentValue.selection != updatedFilteredValue.selection - if (updatedFilteredValue.text.isNotEmpty() && - !isSelectionChangedOnly && - textFieldIndex != values.lastIndex - ) { - focusedIndex = textFieldIndex + 1 - } - onValueChange(values.codeValue()) } - }, - modifier = modifier - .requiredWidth( - rememberTextFieldWidth( - defaultWidth = dimensions.interactiveComponentMinSize, - rowWidth = with(LocalDensity.current) { rowWidthPx.toDp() }, - space = horizontalSpace, - length = validLength - ) - ) - .onPreviewKeyEvent { - if (it.key == Key.Backspace && - it.type == KeyEventType.KeyDown && - textFieldIndex != 0 && - values[textFieldIndex].selection.start == 0 - ) { - values = values.mapIndexed { index, textFieldValue -> - if (index == textFieldIndex - 1) { - TextFieldValue() - } else { - textFieldValue.copy(selection = TextRange.Zero) - } + val isSelectionChangedOnly = currentValue.text == updatedFilteredValue.text && + currentValue.selection != updatedFilteredValue.selection + if (updatedFilteredValue.text.isNotEmpty() && + !isSelectionChangedOnly && + textFieldIndex != values.lastIndex + ) { + focusedIndex = textFieldIndex + 1 + } + onValueChange(values.codeValue()) + } + }, + modifier = Modifier.requiredWidth( + rememberTextFieldWidth( + defaultWidth = 40.dp, + rowWidth = with(LocalDensity.current) { rowWidthPx.toDp() }, + space = horizontalSpace, + length = validLength + ) + ), + textFieldModifier = modifier + .onPreviewKeyEvent { + if (it.key == Key.Backspace && + it.type == KeyEventType.KeyDown && + textFieldIndex != 0 && + values[textFieldIndex].selection.start == 0 + ) { + values = values.mapIndexed { index, textFieldValue -> + if (index == textFieldIndex - 1) { + TextFieldValue() + } else { + textFieldValue.copy(selection = TextRange.Zero) } - focusManager.moveFocus(FocusDirection.Previous) - onValueChange(values.codeValue()) } - false + focusManager.moveFocus(FocusDirection.Previous) + onValueChange(values.codeValue()) } - .focusRequester(focusRequester) - .onFocusChanged { - if (it.isFocused) { - focusedIndex = textFieldIndex - } - }, - contentPadding = PaddingValues(0.dp), - style = align(style), - enabled = enabled, - isError = isError, - keyboardOptions = keyboardOptions, - keyboardActions = keyboardActions - ) - if (isFocused && textFieldIndex == focusedIndex) { - if (lifecycleEvent == Lifecycle.Event.ON_RESUME) { - PORequestFocus(focusRequester, lifecycleEvent) - } else { - PORequestFocus(focusRequester) + false } + .focusRequester(focusRequester) + .onFocusChanged { + if (it.isFocused) { + focusedIndex = textFieldIndex + } + }, + contentPadding = PaddingValues(spacing.space0), + fieldStyle = align(style), + enabled = enabled, + isError = isError, + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions + ) + if (isFocused && textFieldIndex == focusedIndex) { + if (lifecycleEvent == Lifecycle.Event.ON_RESUME) { + PORequestFocus(focusRequester, lifecycleEvent) + } else { + PORequestFocus(focusRequester) } } } @@ -241,19 +291,6 @@ object POCodeField { val default: POField.Style @Composable get() = POField.default.let { - val text = POText.Style( - color = colors.text.primary, - textStyle = typography.title - ) - it.copy( - normal = it.normal.copy(text = text), - error = it.error.copy(text = text), - focused = it.focused.copy(text = text) - ) - } - - val default2: POField.Style - @Composable get() = POField.default2.let { val text = POText.Style( color = colors.text.primary, textStyle = typography.s20(FontWeight.Medium) diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/code/POCodeField2.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/code/POCodeField2.kt deleted file mode 100644 index 66c74caea..000000000 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/code/POCodeField2.kt +++ /dev/null @@ -1,279 +0,0 @@ -package com.processout.sdk.ui.core.component.field.code - -import androidx.compose.foundation.focusGroup -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusDirection -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.input.key.* -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.platform.* -import androidx.compose.ui.text.TextRange -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.unit.LayoutDirection -import androidx.compose.ui.unit.dp -import androidx.lifecycle.Lifecycle -import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi -import com.processout.sdk.ui.core.component.POMessageBox -import com.processout.sdk.ui.core.component.PORequestFocus -import com.processout.sdk.ui.core.component.POText -import com.processout.sdk.ui.core.component.field.POField -import com.processout.sdk.ui.core.component.field.POField.stateStyle -import com.processout.sdk.ui.core.component.field.code.POCodeField.align -import com.processout.sdk.ui.core.component.field.code.POCodeField.rememberTextFieldWidth -import com.processout.sdk.ui.core.component.field.code.POCodeField.validLength -import com.processout.sdk.ui.core.component.field.text.POTextField2 -import com.processout.sdk.ui.core.component.texttoolbar.ProcessOutTextToolbar -import com.processout.sdk.ui.core.state.POInputFilter -import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing - -/** @suppress */ -@ProcessOutInternalApi -@Composable -fun POCodeField2( - value: TextFieldValue, - onValueChange: (TextFieldValue) -> Unit, - modifier: Modifier = Modifier, - textFieldModifier: Modifier = Modifier, - fieldStyle: POField.Style = POCodeField.default2, - descriptionStyle: POMessageBox.Style = POMessageBox.error2, - length: Int = POCodeField.LengthMax, - label: String? = null, - description: String? = null, - enabled: Boolean = true, - isError: Boolean = false, - isFocused: Boolean = false, - lifecycleEvent: Lifecycle.Event? = null, - inputFilter: POInputFilter? = null, - keyboardOptions: KeyboardOptions = KeyboardOptions.Default, - keyboardActions: KeyboardActions = KeyboardActions.Default -) { - Column(modifier = modifier) { - if (!label.isNullOrBlank()) { - val fieldStateStyle = fieldStyle.stateStyle( - isError = isError, - isFocused = isFocused - ) - POText( - text = label, - modifier = Modifier.padding(bottom = spacing.space12), - color = fieldStateStyle.label.color, - style = fieldStateStyle.label.textStyle - ) - } - Code( - value = value, - onValueChange = onValueChange, - style = fieldStyle, - length = length, - enabled = enabled, - isError = isError, - isFocused = isFocused, - lifecycleEvent = lifecycleEvent, - inputFilter = inputFilter, - keyboardOptions = keyboardOptions, - keyboardActions = keyboardActions, - modifier = textFieldModifier - ) - POMessageBox( - text = description, - modifier = Modifier.padding(top = spacing.space12), - style = descriptionStyle - ) - } -} - -@Composable -private fun Code( - value: TextFieldValue, - onValueChange: (TextFieldValue) -> Unit, - style: POField.Style, - length: Int, - enabled: Boolean, - isError: Boolean, - isFocused: Boolean, - lifecycleEvent: Lifecycle.Event?, - inputFilter: POInputFilter?, - keyboardOptions: KeyboardOptions, - keyboardActions: KeyboardActions, - modifier: Modifier = Modifier -) { - val validLength = remember(length) { validLength(length) } - var values by remember(validLength) { mutableStateOf(values(value.text, validLength, inputFilter)) } - var focusedIndex by remember(validLength) { mutableIntStateOf(values.focusedIndex()) } - val clipboardManager = LocalClipboardManager.current - CompositionLocalProvider( - LocalLayoutDirection provides LayoutDirection.Ltr, - LocalTextToolbar provides ProcessOutTextToolbar( - view = LocalView.current, - onPasteRequested = { - if (clipboardManager.hasText()) { - val pastedValues = values( - text = clipboardManager.getText()?.text ?: String(), - length = validLength, - inputFilter = inputFilter - ) - if (!pastedValues.all { it.text.isEmpty() }) { - values = pastedValues - focusedIndex = values.focusedIndex() - onValueChange(values.codeValue()) - } - } - }, - hideUnspecifiedActions = true - ) - ) { - var rowWidthPx by remember { mutableIntStateOf(0) } - val horizontalSpace = spacing.space8 - Row( - modifier = Modifier - .focusGroup() - .fillMaxWidth() - .onGloballyPositioned { rowWidthPx = it.size.width }, - horizontalArrangement = Arrangement.spacedBy(horizontalSpace), - verticalAlignment = Alignment.CenterVertically - ) { - val focusManager = LocalFocusManager.current - for (textFieldIndex in values.indices) { - val focusRequester = remember { FocusRequester() } - POTextField2( - value = values[textFieldIndex], - onValueChange = { updatedValue -> - if (updatedValue.selection.length == 0) { - val currentValue = values[textFieldIndex] - val updatedFilteredValue = inputFilter?.filter(updatedValue) ?: updatedValue - values = values.mapIndexed { index, textFieldValue -> - if (index == textFieldIndex) { - val updatedText = updatedFilteredValue.text.firstOrNull()?.toString() ?: String() - val isTextChanged = textFieldValue.text != updatedText - TextFieldValue( - text = updatedText, - selection = if (isTextChanged) { - TextRange(updatedText.length) - } else { - updatedFilteredValue.selection - } - ) - } else { - textFieldValue.copy(selection = TextRange.Zero) - } - } - if (textFieldIndex != values.lastIndex && - updatedFilteredValue.text.length == 2 && - updatedFilteredValue.selection.start == 2 - ) { - val nextText = updatedFilteredValue.text.last().toString() - values = values.mapIndexed { index, textFieldValue -> - if (index == textFieldIndex + 1) { - TextFieldValue( - text = nextText, - selection = TextRange(nextText.length) - ) - } else { - textFieldValue.copy(selection = TextRange.Zero) - } - } - } - val isSelectionChangedOnly = currentValue.text == updatedFilteredValue.text && - currentValue.selection != updatedFilteredValue.selection - if (updatedFilteredValue.text.isNotEmpty() && - !isSelectionChangedOnly && - textFieldIndex != values.lastIndex - ) { - focusedIndex = textFieldIndex + 1 - } - onValueChange(values.codeValue()) - } - }, - modifier = Modifier.requiredWidth( - rememberTextFieldWidth( - defaultWidth = 40.dp, - rowWidth = with(LocalDensity.current) { rowWidthPx.toDp() }, - space = horizontalSpace, - length = validLength - ) - ), - textFieldModifier = modifier - .onPreviewKeyEvent { - if (it.key == Key.Backspace && - it.type == KeyEventType.KeyDown && - textFieldIndex != 0 && - values[textFieldIndex].selection.start == 0 - ) { - values = values.mapIndexed { index, textFieldValue -> - if (index == textFieldIndex - 1) { - TextFieldValue() - } else { - textFieldValue.copy(selection = TextRange.Zero) - } - } - focusManager.moveFocus(FocusDirection.Previous) - onValueChange(values.codeValue()) - } - false - } - .focusRequester(focusRequester) - .onFocusChanged { - if (it.isFocused) { - focusedIndex = textFieldIndex - } - }, - contentPadding = PaddingValues(spacing.space0), - fieldStyle = align(style), - enabled = enabled, - isError = isError, - keyboardOptions = keyboardOptions, - keyboardActions = keyboardActions - ) - if (isFocused && textFieldIndex == focusedIndex) { - if (lifecycleEvent == Lifecycle.Event.ON_RESUME) { - PORequestFocus(focusRequester, lifecycleEvent) - } else { - PORequestFocus(focusRequester) - } - } - } - } - } -} - -private fun values( - text: String, - length: Int, - inputFilter: POInputFilter? -): List { - val values = mutableListOf() - while (values.size < length) { - values.add(TextFieldValue()) - } - val filteredText = inputFilter?.filter(TextFieldValue(text = text))?.text ?: text - filteredText - .take(length) - .forEachIndexed { index, char -> - val value = char.toString() - values[index] = TextFieldValue( - text = value, - selection = TextRange(value.length) - ) - } - return values -} - -private fun List.focusedIndex(): Int { - forEachIndexed { index, textFieldValue -> - if (textFieldValue.text.isEmpty()) { - return index - } - } - return lastIndex -} - -private fun List.codeValue() = TextFieldValue( - text = joinToString(separator = String()) { it.text } -) diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/code/POLabeledCodeField.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/code/POLabeledCodeField.kt deleted file mode 100644 index c2e4e048f..000000000 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/code/POLabeledCodeField.kt +++ /dev/null @@ -1,59 +0,0 @@ -package com.processout.sdk.ui.core.component.field.code - -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.input.TextFieldValue -import androidx.lifecycle.Lifecycle -import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi -import com.processout.sdk.ui.core.component.field.LabeledFieldLayout -import com.processout.sdk.ui.core.component.field.POField -import com.processout.sdk.ui.core.component.field.POFieldLabels -import com.processout.sdk.ui.core.state.POInputFilter - -/** @suppress */ -@ProcessOutInternalApi -@Composable -fun POLabeledCodeField( - value: TextFieldValue, - onValueChange: (TextFieldValue) -> Unit, - title: String, - description: String?, - modifier: Modifier = Modifier, - fieldStyle: POField.Style = POCodeField.default, - labelsStyle: POFieldLabels.Style = POFieldLabels.default, - length: Int = POCodeField.LengthMax, - horizontalAlignment: Alignment.Horizontal = Alignment.CenterHorizontally, - enabled: Boolean = true, - isError: Boolean = false, - isFocused: Boolean = false, - lifecycleEvent: Lifecycle.Event? = null, - inputFilter: POInputFilter? = null, - keyboardOptions: KeyboardOptions = KeyboardOptions.Default, - keyboardActions: KeyboardActions = KeyboardActions.Default -) { - LabeledFieldLayout( - title = title, - description = description, - style = labelsStyle, - horizontalAlignment = horizontalAlignment - ) { - POCodeField( - value = value, - onValueChange = onValueChange, - modifier = modifier, - style = fieldStyle, - length = length, - horizontalAlignment = horizontalAlignment, - enabled = enabled, - isError = isError, - isFocused = isFocused, - lifecycleEvent = lifecycleEvent, - inputFilter = inputFilter, - keyboardOptions = keyboardOptions, - keyboardActions = keyboardActions - ) - } -} diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/dropdown/PODropdownField.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/dropdown/PODropdownField.kt index 4475c289e..05dfb5559 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/dropdown/PODropdownField.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/dropdown/PODropdownField.kt @@ -15,6 +15,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.rotate +import androidx.compose.ui.draw.scale import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalFocusManager @@ -29,6 +30,7 @@ import com.processout.sdk.ui.core.R import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi import com.processout.sdk.ui.core.component.POBorderStroke import com.processout.sdk.ui.core.component.POIme.isImeVisibleAsState +import com.processout.sdk.ui.core.component.POMessageBox import com.processout.sdk.ui.core.component.POText import com.processout.sdk.ui.core.component.field.POField import com.processout.sdk.ui.core.component.field.POField.stateStyle @@ -50,14 +52,19 @@ fun PODropdownField( onValueChange: (TextFieldValue) -> Unit, availableValues: POImmutableList, modifier: Modifier = Modifier, + textFieldModifier: Modifier = Modifier, contentPadding: PaddingValues = POField.contentPadding, fieldStyle: POField.Style = POField.default, menuStyle: PODropdownField.MenuStyle = PODropdownField.defaultMenu, + descriptionStyle: POMessageBox.Style = POMessageBox.error, menuMatchesTextFieldWidth: Boolean = true, preferFormattedTextSelection: Boolean = false, enabled: Boolean = true, isError: Boolean = false, - placeholder: String? = null + label: String? = null, + placeholder: String? = null, + description: String? = null, + contentDescription: String? = null ) { MaterialTheme( colorScheme = MaterialTheme.colorScheme.copy(surface = Color.Transparent), @@ -76,6 +83,7 @@ fun PODropdownField( } } ExposedDropdownMenuBox( + modifier = modifier, expanded = expanded, onExpandedChange = { if (enabled) { @@ -97,29 +105,36 @@ fun PODropdownField( ) } ?: TextFieldValue(), onValueChange = {}, - modifier = modifier + modifier = Modifier.fillMaxWidth(), + textFieldModifier = textFieldModifier .menuAnchor(MenuAnchorType.PrimaryNotEditable) .onFocusChanged { isFocused = it.isFocused }, contentPadding = contentPadding, - style = fieldStyle, + fieldStyle = fieldStyle, + descriptionStyle = descriptionStyle, enabled = enabled, readOnly = true, isDropdown = true, isError = isError, + label = label, placeholder = placeholder, + description = description, + contentDescription = contentDescription, trailingIcon = { Icon( - painter = painterResource(id = R.drawable.po_dropdown_arrow), + painter = painterResource(id = R.drawable.po_chevron_down), contentDescription = null, - modifier = Modifier.rotate(if (expanded) 180f else 0f), - tint = fieldStateStyle.text.color + modifier = Modifier + .scale(1.1f) + .rotate(if (expanded) 180f else 0f), + tint = fieldStateStyle.label.color ) } ) val menuItemHeight = dimensions.formComponentMinHeight - val menuVerticalPaddings = spacing.large + val menuVerticalPaddings = spacing.space16 val maxMenuHeight = remember { menuItemHeight * PODropdownField.MaxVisibleMenuItems + menuVerticalPaddings } DropdownMenu( expanded = expanded, @@ -171,7 +186,7 @@ private fun MenuItem( indication = ripple(color = style.rippleColor) ) .fillMaxWidth() - .padding(horizontal = spacing.large), + .padding(horizontal = spacing.space16), contentAlignment = Alignment.CenterStart ) { POText( @@ -198,15 +213,6 @@ object PODropdownField { ) val defaultMenu: MenuStyle - @Composable get() = MenuStyle( - text = POText.body2, - backgroundColor = colors.surface.neutral, - rippleColor = colors.text.muted, - shape = shapes.roundedCornersSmall, - border = POBorderStroke(width = 0.dp, color = Color.Transparent) - ) - - val defaultMenu2: MenuStyle @Composable get() = MenuStyle( text = POText.Style( color = colors.text.secondary, diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/dropdown/PODropdownField2.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/dropdown/PODropdownField2.kt deleted file mode 100644 index cb65f67b4..000000000 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/dropdown/PODropdownField2.kt +++ /dev/null @@ -1,189 +0,0 @@ -@file:OptIn(ExperimentalMaterial3Api::class) - -package com.processout.sdk.ui.core.component.field.dropdown - -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.rotate -import androidx.compose.ui.draw.scale -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.window.PopupProperties -import com.processout.sdk.ui.core.R -import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi -import com.processout.sdk.ui.core.component.POIme.isImeVisibleAsState -import com.processout.sdk.ui.core.component.POMessageBox -import com.processout.sdk.ui.core.component.POText -import com.processout.sdk.ui.core.component.field.POField -import com.processout.sdk.ui.core.component.field.POField.stateStyle -import com.processout.sdk.ui.core.component.field.text.POTextField2 -import com.processout.sdk.ui.core.state.POAvailableValue -import com.processout.sdk.ui.core.state.POImmutableList -import com.processout.sdk.ui.core.theme.ProcessOutTheme.dimensions -import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing - -/** @suppress */ -@ProcessOutInternalApi -@Composable -fun PODropdownField2( - value: TextFieldValue, - onValueChange: (TextFieldValue) -> Unit, - availableValues: POImmutableList, - modifier: Modifier = Modifier, - textFieldModifier: Modifier = Modifier, - contentPadding: PaddingValues = POField.contentPadding2, - fieldStyle: POField.Style = POField.default2, - menuStyle: PODropdownField.MenuStyle = PODropdownField.defaultMenu2, - descriptionStyle: POMessageBox.Style = POMessageBox.error2, - menuMatchesTextFieldWidth: Boolean = true, - preferFormattedTextSelection: Boolean = false, - enabled: Boolean = true, - isError: Boolean = false, - label: String? = null, - placeholder: String? = null, - description: String? = null, - contentDescription: String? = null -) { - MaterialTheme( - colorScheme = MaterialTheme.colorScheme.copy(surface = Color.Transparent), - shapes = MaterialTheme.shapes.copy(extraSmall = menuStyle.shape) - ) { - var expanded by remember { mutableStateOf(false) } - var expanding by remember { mutableStateOf(false) } - val isImeVisible by isImeVisibleAsState(policy = structuralEqualityPolicy()) - if (expanding && isImeVisible) { - LocalFocusManager.current.clearFocus(force = true) - } - LaunchedEffect(expanding, isImeVisible) { - if (expanding && !isImeVisible) { - expanding = false - expanded = true - } - } - ExposedDropdownMenuBox( - modifier = modifier, - expanded = expanded, - onExpandedChange = { - if (enabled) { - when (it) { - true -> expanding = true - false -> expanded = false - } - } - } - ) { - var isFocused by remember { mutableStateOf(false) } - val fieldStateStyle = fieldStyle.stateStyle(isError = isError, isFocused = isFocused) - POTextField2( - value = availableValues.elements.find { it.value == value.text } - ?.let { - TextFieldValue( - text = if (preferFormattedTextSelection && it.formattedText != null) - it.formattedText else it.text - ) - } ?: TextFieldValue(), - onValueChange = {}, - modifier = Modifier.fillMaxWidth(), - textFieldModifier = textFieldModifier - .menuAnchor(MenuAnchorType.PrimaryNotEditable) - .onFocusChanged { - isFocused = it.isFocused - }, - contentPadding = contentPadding, - fieldStyle = fieldStyle, - descriptionStyle = descriptionStyle, - enabled = enabled, - readOnly = true, - isDropdown = true, - isError = isError, - label = label, - placeholder = placeholder, - description = description, - contentDescription = contentDescription, - trailingIcon = { - Icon( - painter = painterResource(id = R.drawable.po_chevron_down), - contentDescription = null, - modifier = Modifier - .scale(1.1f) - .rotate(if (expanded) 180f else 0f), - tint = fieldStateStyle.label.color - ) - } - ) - val menuItemHeight = dimensions.formComponentMinHeight - val menuVerticalPaddings = spacing.large - val maxMenuHeight = remember { menuItemHeight * PODropdownField.MaxVisibleMenuItems + menuVerticalPaddings } - DropdownMenu( - expanded = expanded, - onDismissRequest = { expanded = false }, - modifier = Modifier - .exposedDropdownSize(matchTextFieldWidth = menuMatchesTextFieldWidth) - .heightIn(max = maxMenuHeight) - .border( - width = menuStyle.border.width, - color = menuStyle.border.color, - shape = menuStyle.shape - ) - .background(color = menuStyle.backgroundColor), - properties = PopupProperties( - focusable = true, - dismissOnBackPress = true, - dismissOnClickOutside = true - ) - ) { - availableValues.elements.forEach { availableValue -> - MenuItem( - availableValue = availableValue, - onClick = { - expanded = false - onValueChange(TextFieldValue(it.value)) - }, - modifier = Modifier.requiredHeight(menuItemHeight), - style = menuStyle - ) - } - } - } - } -} - -@Composable -private fun MenuItem( - availableValue: POAvailableValue, - onClick: (POAvailableValue) -> Unit, - modifier: Modifier = Modifier, - style: PODropdownField.MenuStyle, - interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } -) { - Box( - modifier = modifier - .clickable( - onClick = { onClick(availableValue) }, - interactionSource = interactionSource, - indication = ripple(color = style.rippleColor) - ) - .fillMaxWidth() - .padding(horizontal = spacing.large), - contentAlignment = Alignment.CenterStart - ) { - POText( - text = availableValue.text, - color = style.text.color, - style = style.text.textStyle, - overflow = TextOverflow.Ellipsis, - maxLines = 1 - ) - } -} diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/dropdown/POLabeledDropdownField.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/dropdown/POLabeledDropdownField.kt deleted file mode 100644 index e758566cc..000000000 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/dropdown/POLabeledDropdownField.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.processout.sdk.ui.core.component.field.dropdown - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.input.TextFieldValue -import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi -import com.processout.sdk.ui.core.component.field.LabeledFieldLayout -import com.processout.sdk.ui.core.component.field.POField -import com.processout.sdk.ui.core.component.field.POFieldLabels -import com.processout.sdk.ui.core.state.POAvailableValue -import com.processout.sdk.ui.core.state.POImmutableList - -/** @suppress */ -@ProcessOutInternalApi -@Composable -fun POLabeledDropdownField( - value: TextFieldValue, - onValueChange: (TextFieldValue) -> Unit, - availableValues: POImmutableList, - title: String, - description: String?, - modifier: Modifier = Modifier, - fieldStyle: POField.Style = POField.default, - labelsStyle: POFieldLabels.Style = POFieldLabels.default, - menuStyle: PODropdownField.MenuStyle = PODropdownField.defaultMenu, - menuMatchesTextFieldWidth: Boolean = true, - preferFormattedTextSelection: Boolean = false, - enabled: Boolean = true, - isError: Boolean = false, - placeholder: String? = null -) { - LabeledFieldLayout( - title = title, - description = description, - style = labelsStyle - ) { - PODropdownField( - value = value, - onValueChange = onValueChange, - availableValues = availableValues, - modifier = modifier, - fieldStyle = fieldStyle, - menuStyle = menuStyle, - menuMatchesTextFieldWidth = menuMatchesTextFieldWidth, - preferFormattedTextSelection = preferFormattedTextSelection, - enabled = enabled, - isError = isError, - placeholder = placeholder - ) - } -} diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/phone/POPhoneNumberField.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/phone/POPhoneNumberField.kt index 47623febb..c568b882a 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/phone/POPhoneNumberField.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/phone/POPhoneNumberField.kt @@ -16,8 +16,7 @@ import com.processout.sdk.ui.core.component.POMessageBox import com.processout.sdk.ui.core.component.PORequestFocus import com.processout.sdk.ui.core.component.field.POField import com.processout.sdk.ui.core.component.field.dropdown.PODropdownField -import com.processout.sdk.ui.core.component.field.dropdown.PODropdownField2 -import com.processout.sdk.ui.core.component.field.text.POTextField2 +import com.processout.sdk.ui.core.component.field.text.POTextField import com.processout.sdk.ui.core.state.POPhoneNumberFieldState import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing @@ -29,15 +28,15 @@ fun POPhoneNumberField( onValueChange: (TextFieldValue, TextFieldValue) -> Unit, modifier: Modifier = Modifier, textFieldModifier: Modifier = Modifier, - fieldStyle: POField.Style = POField.default2, - dropdownMenuStyle: PODropdownField.MenuStyle = PODropdownField.defaultMenu2, - descriptionStyle: POMessageBox.Style = POMessageBox.error2, + fieldStyle: POField.Style = POField.default, + dropdownMenuStyle: PODropdownField.MenuStyle = PODropdownField.defaultMenu, + descriptionStyle: POMessageBox.Style = POMessageBox.error, keyboardActions: KeyboardActions = KeyboardActions.Default ) { Column(modifier = modifier) { Row(modifier = Modifier.fillMaxWidth()) { var requestFocus by remember { mutableStateOf(false) } - PODropdownField2( + PODropdownField( value = state.regionCode, onValueChange = { regionCode -> requestFocus = true @@ -60,7 +59,7 @@ fun POPhoneNumberField( ) val focusRequester = remember { FocusRequester() } val phoneNumberUtil = remember { PhoneNumberUtil.getInstance() } - POTextField2( + POTextField( value = state.number, onValueChange = { number -> if (number.text.startsWith('+')) { diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/POLabeledRadioField.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/POLabeledRadioField.kt deleted file mode 100644 index 94d427eba..000000000 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/POLabeledRadioField.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.processout.sdk.ui.core.component.field.radio - -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.input.TextFieldValue -import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi -import com.processout.sdk.ui.core.component.field.LabeledFieldLayout -import com.processout.sdk.ui.core.component.field.POFieldLabels -import com.processout.sdk.ui.core.state.POAvailableValue -import com.processout.sdk.ui.core.state.POImmutableList - -/** @suppress */ -@ProcessOutInternalApi -@Composable -fun POLabeledRadioField( - value: TextFieldValue, - onValueChange: (TextFieldValue) -> Unit, - availableValues: POImmutableList, - title: String, - description: String?, - modifier: Modifier = Modifier, - radioGroupStyle: PORadioGroup.Style = PORadioGroup.default, - labelsStyle: POFieldLabels.Style = POFieldLabels.default, - isError: Boolean = false, - interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } -) { - LabeledFieldLayout( - title = title, - description = description, - style = labelsStyle - ) { - PORadioGroup( - value = value.text, - onValueChange = { onValueChange(TextFieldValue(text = it)) }, - availableValues = availableValues, - modifier = modifier, - style = radioGroupStyle, - isError = isError, - interactionSource = interactionSource - ) - } -} diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/PORadioButton.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/PORadioButton.kt index 76f81e3e4..dbcda69d8 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/PORadioButton.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/PORadioButton.kt @@ -56,14 +56,6 @@ object PORadioButton { ) val default: Style - @Composable get() = Style( - normalColor = colors.input.borderDefault, - selectedColor = colors.button.primaryBackgroundDefault, - errorColor = colors.input.borderError, - disabledColor = colors.input.borderDisabled - ) - - val default2: Style @Composable get() = Style( normalColor = colors.checkRadio.borderDefault, selectedColor = colors.checkRadio.borderActive, diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/PORadioField.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/PORadioField.kt index 572173274..8756606d4 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/PORadioField.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/PORadioField.kt @@ -45,7 +45,7 @@ fun PORadioField( availableValues: POImmutableList, modifier: Modifier = Modifier, fieldStyle: PORadioField.Style = PORadioField.default, - descriptionStyle: POMessageBox.Style = POMessageBox.error2, + descriptionStyle: POMessageBox.Style = POMessageBox.error, title: String? = null, description: String? = null, isError: Boolean = false @@ -163,11 +163,11 @@ object PORadioField { color = colors.text.secondary, textStyle = typography.s15(FontWeight.Medium) ), - radioButtonColor = PORadioButton.default2.normalColor, + radioButtonColor = PORadioButton.default.normalColor, rowBackgroundColor = colors.surface.default, rowRippleColor = colors.surface.darkoutRipple, shape = shapes.roundedCorners6, - border = POBorderStroke(width = 1.5.dp, color = colors.input.borderDefault2) + border = POBorderStroke(width = 1.5.dp, color = colors.input.borderDefault) ), selected = StateStyle( title = POText.Style( @@ -178,11 +178,11 @@ object PORadioField { color = colors.text.primary, textStyle = typography.s15(FontWeight.Medium) ), - radioButtonColor = PORadioButton.default2.selectedColor, + radioButtonColor = PORadioButton.default.selectedColor, rowBackgroundColor = colors.surface.darkout, rowRippleColor = null, shape = shapes.roundedCorners6, - border = POBorderStroke(width = 1.5.dp, color = colors.input.borderDefault2) + border = POBorderStroke(width = 1.5.dp, color = colors.input.borderDefault) ), error = StateStyle( title = POText.Style( @@ -193,7 +193,7 @@ object PORadioField { color = colors.text.secondary, textStyle = typography.s15(FontWeight.Medium) ), - radioButtonColor = PORadioButton.default2.errorColor, + radioButtonColor = PORadioButton.default.errorColor, rowBackgroundColor = colors.surface.default, rowRippleColor = colors.surface.darkoutRipple, shape = shapes.roundedCorners6, @@ -208,11 +208,11 @@ object PORadioField { color = colors.text.disabled, textStyle = typography.s15(FontWeight.Medium) ), - radioButtonColor = PORadioButton.default2.disabledColor, + radioButtonColor = PORadioButton.default.disabledColor, rowBackgroundColor = colors.surface.default, rowRippleColor = null, shape = shapes.roundedCorners6, - border = POBorderStroke(width = 1.5.dp, color = colors.input.borderDefault2) + border = POBorderStroke(width = 1.5.dp, color = colors.input.borderDefault) ) ) diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/PORadioGroup.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/PORadioGroup.kt deleted file mode 100644 index 9986579dd..000000000 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/radio/PORadioGroup.kt +++ /dev/null @@ -1,197 +0,0 @@ -package com.processout.sdk.ui.core.component.field.radio - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Immutable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.colorResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi -import com.processout.sdk.ui.core.component.POText -import com.processout.sdk.ui.core.component.POText.measuredPaddingTop -import com.processout.sdk.ui.core.component.field.radio.PORadioGroup.textStyle -import com.processout.sdk.ui.core.component.field.radio.PORadioGroup.toRadioButtonStyle -import com.processout.sdk.ui.core.state.POAvailableValue -import com.processout.sdk.ui.core.state.POImmutableList -import com.processout.sdk.ui.core.style.PORadioButtonStateStyle -import com.processout.sdk.ui.core.style.PORadioButtonStyle -import com.processout.sdk.ui.core.style.PORadioFieldStateStyle -import com.processout.sdk.ui.core.style.PORadioFieldStyle -import com.processout.sdk.ui.core.theme.ProcessOutTheme.colors -import com.processout.sdk.ui.core.theme.ProcessOutTheme.dimensions -import com.processout.sdk.ui.core.theme.ProcessOutTheme.typography - -/** @suppress */ -@ProcessOutInternalApi -@Composable -fun PORadioGroup( - value: String, - onValueChange: (String) -> Unit, - availableValues: POImmutableList, - modifier: Modifier = Modifier, - style: PORadioGroup.Style = PORadioGroup.default, - isError: Boolean = false, - interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } -) { - Column( - modifier = modifier - ) { - availableValues.elements.forEach { - val onClick = { onValueChange(it.value) } - Row( - modifier = Modifier - .fillMaxWidth() - .requiredHeightIn(min = dimensions.formComponentMinHeight) - .clickable( - onClick = onClick, - interactionSource = interactionSource, - indication = null - ) - ) { - val selected = it.value == value - PORadioButton( - selected = selected, - onClick = onClick, - style = style.toRadioButtonStyle(), - isError = isError - ) - val textStyle = textStyle(style = style, selected = selected, isError = isError) - POText( - text = it.text, - modifier = Modifier.padding( - start = 10.dp, - top = measuredPaddingTop( - textStyle = textStyle.textStyle, - componentHeight = dimensions.formComponentMinHeight - ) - ), - color = textStyle.color, - style = textStyle.textStyle - ) - } - } - } -} - -/** @suppress */ -@ProcessOutInternalApi -object PORadioGroup { - - @Immutable - data class Style( - val normal: StateStyle, - val selected: StateStyle, - val error: StateStyle, - val disabled: StateStyle - ) - - @Immutable - data class StateStyle( - val buttonColor: Color, - val text: POText.Style - ) - - val default: Style - @Composable get() = Style( - normal = StateStyle( - buttonColor = colors.input.borderDefault, - text = POText.label1 - ), - selected = StateStyle( - buttonColor = colors.button.primaryBackgroundDefault, - text = POText.label1 - ), - error = StateStyle( - buttonColor = colors.input.borderError, - text = POText.label1 - ), - disabled = StateStyle( - buttonColor = colors.input.borderDisabled, - text = POText.Style( - color = colors.text.disabled, - textStyle = typography.label1 - ) - ) - ) - - val default2: Style - @Composable get() = Style( - normal = StateStyle( - buttonColor = PORadioButton.default2.normalColor, - text = POText.Style( - color = colors.text.secondary, - textStyle = typography.s15(FontWeight.Medium) - ) - ), - selected = StateStyle( - buttonColor = PORadioButton.default2.selectedColor, - text = POText.Style( - color = colors.text.secondary, - textStyle = typography.s15(FontWeight.Medium) - ) - ), - error = StateStyle( - buttonColor = PORadioButton.default2.errorColor, - text = POText.Style( - color = colors.text.secondary, - textStyle = typography.s15(FontWeight.Medium) - ) - ), - disabled = StateStyle( - buttonColor = PORadioButton.default2.disabledColor, - text = POText.Style( - color = colors.text.disabled, - textStyle = typography.s15(FontWeight.Medium) - ) - ) - ) - - @Composable - fun custom(style: PORadioButtonStyle) = Style( - normal = style.normal.toStateStyle(), - selected = style.selected.toStateStyle(), - error = style.error.toStateStyle(), - disabled = style.disabled?.toStateStyle() ?: default.disabled - ) - - @Composable - private fun PORadioButtonStateStyle.toStateStyle() = StateStyle( - buttonColor = colorResource(id = buttonColorResId), - text = POText.custom(style = text) - ) - - @Composable - fun custom(style: PORadioFieldStyle) = Style( - normal = style.normal.toStateStyle(), - selected = style.selected.toStateStyle(), - error = style.error.toStateStyle(), - disabled = style.disabled?.toStateStyle() ?: default.disabled - ) - - @Composable - private fun PORadioFieldStateStyle.toStateStyle() = StateStyle( - buttonColor = colorResource(id = radioButtonColorResId), - text = POText.custom(style = option) - ) - - fun Style.toRadioButtonStyle() = PORadioButton.Style( - normalColor = normal.buttonColor, - selectedColor = selected.buttonColor, - errorColor = error.buttonColor, - disabledColor = disabled.buttonColor - ) - - internal fun textStyle( - style: Style, - selected: Boolean, - isError: Boolean - ): POText.Style = - if (isError) style.error.text - else if (selected) style.selected.text - else style.normal.text -} diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POBasicTextField.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POBasicTextField.kt new file mode 100644 index 000000000..dd34ff382 --- /dev/null +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POBasicTextField.kt @@ -0,0 +1,187 @@ +@file:OptIn(ExperimentalMaterial3Api::class) + +package com.processout.sdk.ui.core.component.field.text + +import androidx.compose.animation.animateContentSize +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.spring +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.text.selection.LocalTextSelectionColors +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.OutlinedTextFieldDefaults +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.semantics.clearAndSetSemantics +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi +import com.processout.sdk.ui.core.component.POText +import com.processout.sdk.ui.core.component.field.POField +import com.processout.sdk.ui.core.component.field.POField.ContainerBox +import com.processout.sdk.ui.core.component.field.POField.stateStyle +import com.processout.sdk.ui.core.component.field.POField.textSelectionColors +import com.processout.sdk.ui.core.component.field.POField.textStyle +import com.processout.sdk.ui.core.extension.conditional +import com.processout.sdk.ui.core.theme.ProcessOutTheme.dimensions +import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing + +/** @suppress */ +@ProcessOutInternalApi +@Composable +fun POBasicTextField( + value: TextFieldValue, + onValueChange: (TextFieldValue) -> Unit, + modifier: Modifier = Modifier, + minHeight: Dp = dimensions.fieldMinHeight, + contentPadding: PaddingValues = POField.contentPadding, + style: POField.Style = POField.default, + enabled: Boolean = true, + readOnly: Boolean = false, + isDropdown: Boolean = false, + isError: Boolean = false, + forceTextDirectionLtr: Boolean = false, + label: String? = null, + placeholder: String? = null, + contentDescription: String? = null, + leadingIcon: @Composable (() -> Unit)? = null, + trailingIcon: @Composable (() -> Unit)? = null, + visualTransformation: VisualTransformation = VisualTransformation.None, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + singleLine: Boolean = true, + maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, + minLines: Int = 1, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } +) { + var isFocused by remember { mutableStateOf(false) } + val stateStyle = style.stateStyle(isError = isError, isFocused = isFocused) + CompositionLocalProvider( + LocalTextSelectionColors provides textSelectionColors(stateStyle.controlsTintColor) + ) { + BasicTextField( + value = value, + onValueChange = onValueChange, + modifier = modifier + .requiredHeightIn(min = minHeight) + .onFocusChanged { + isFocused = it.isFocused + } + .conditional(!contentDescription.isNullOrBlank()) { + if (isDropdown) { + clearAndSetSemantics { + this.contentDescription = "${value.text} $contentDescription" + } + } else { + semantics { + this.contentDescription = contentDescription ?: String() + } + } + }, + enabled = enabled, + readOnly = readOnly, + textStyle = textStyle( + style = stateStyle.text, + forceTextDirectionLtr = forceTextDirectionLtr + ), + cursorBrush = SolidColor(stateStyle.controlsTintColor), + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions, + singleLine = singleLine, + maxLines = maxLines, + minLines = minLines, + visualTransformation = visualTransformation, + interactionSource = interactionSource, + decorationBox = @Composable { innerTextField -> + OutlinedTextFieldDefaults.DecorationBox( + value = value.text, + innerTextField = { + val animationStiffness = Spring.StiffnessMedium + Column( + modifier = Modifier.animateContentSize( + animationSpec = spring(stiffness = animationStiffness) + ) + ) { + val isLabelFloating = value.text.isNotEmpty() || (isFocused && !isDropdown) + if (!label.isNullOrBlank()) { + val fontSizeValue = stateStyle.text.textStyle.fontSize.value + val animatedFontSizeValue by animateFloatAsState( + targetValue = if (isLabelFloating) fontSizeValue * 0.8f else fontSizeValue, + animationSpec = spring(stiffness = animationStiffness) + ) + POText( + text = label, + modifier = Modifier.conditional(!contentDescription.isNullOrBlank()) { + clearAndSetSemantics { } + }, + color = stateStyle.label.color, + style = stateStyle.label.textStyle.copy(fontSize = animatedFontSizeValue.sp), + overflow = TextOverflow.Ellipsis, + maxLines = 1 + ) + if (isLabelFloating) { + Spacer(modifier = Modifier.requiredHeight(spacing.space3)) + } + } + if (isLabelFloating || label.isNullOrBlank()) { + Box { + if (value.text.isEmpty() && !placeholder.isNullOrBlank()) { + POText( + text = placeholder, + modifier = Modifier.clearAndSetSemantics {}, + color = stateStyle.placeholderTextColor, + style = stateStyle.text.textStyle, + overflow = TextOverflow.Ellipsis, + maxLines = 1 + ) + } + innerTextField() + } + } + } + }, + enabled = enabled, + isError = isError, + leadingIcon = leadingIcon, + trailingIcon = trailingIcon, + singleLine = singleLine, + visualTransformation = visualTransformation, + interactionSource = interactionSource, + contentPadding = contentPadding, + container = { + ContainerBox( + style = stateStyle, + enabled = enabled, + isDropdown = isDropdown + ) + } + ) + } + ) + } +} + +@Composable +@Preview(showBackground = true) +private fun POBasicTextFieldPreview() { + Column(modifier = Modifier.padding(16.dp)) { + POBasicTextField( + value = TextFieldValue(text = "test@gmail.com"), + onValueChange = {}, + modifier = Modifier.fillMaxWidth() + ) + } +} diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POLabeledTextField.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POLabeledTextField.kt deleted file mode 100644 index 268e7b214..000000000 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POLabeledTextField.kt +++ /dev/null @@ -1,93 +0,0 @@ -package com.processout.sdk.ui.core.component.field.text - -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.text.input.VisualTransformation -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi -import com.processout.sdk.ui.core.component.field.LabeledFieldLayout -import com.processout.sdk.ui.core.component.field.POField -import com.processout.sdk.ui.core.component.field.POFieldLabels - -/** @suppress */ -@ProcessOutInternalApi -@Composable -fun POLabeledTextField( - value: TextFieldValue, - onValueChange: (TextFieldValue) -> Unit, - title: String, - description: String?, - modifier: Modifier = Modifier, - contentPadding: PaddingValues = POField.contentPadding, - fieldStyle: POField.Style = POField.default, - labelsStyle: POFieldLabels.Style = POFieldLabels.default, - enabled: Boolean = true, - readOnly: Boolean = false, - isDropdown: Boolean = false, - isError: Boolean = false, - forceTextDirectionLtr: Boolean = false, - placeholder: String? = null, - leadingIcon: @Composable (() -> Unit)? = null, - trailingIcon: @Composable (() -> Unit)? = null, - visualTransformation: VisualTransformation = VisualTransformation.None, - keyboardOptions: KeyboardOptions = KeyboardOptions.Default, - keyboardActions: KeyboardActions = KeyboardActions.Default, - singleLine: Boolean = true, - maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, - minLines: Int = 1, - interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } -) { - LabeledFieldLayout( - title = title, - description = description, - style = labelsStyle - ) { - POTextField( - value = value, - onValueChange = onValueChange, - modifier = modifier, - contentPadding = contentPadding, - style = fieldStyle, - enabled = enabled, - readOnly = readOnly, - isDropdown = isDropdown, - isError = isError, - forceTextDirectionLtr = forceTextDirectionLtr, - placeholder = placeholder, - leadingIcon = leadingIcon, - trailingIcon = trailingIcon, - visualTransformation = visualTransformation, - keyboardOptions = keyboardOptions, - keyboardActions = keyboardActions, - singleLine = singleLine, - maxLines = maxLines, - minLines = minLines, - interactionSource = interactionSource - ) - } -} - -@Composable -@Preview(showBackground = true) -private fun POLabeledTextFieldPreview() { - Column(modifier = Modifier.padding(16.dp)) { - POLabeledTextField( - title = "Title", - value = TextFieldValue(text = "test@gmail.com"), - onValueChange = {}, - modifier = Modifier.fillMaxWidth(), - isError = true, - description = "This is error message." - ) - } -} diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POTextField.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POTextField.kt index 2531cea2d..d98fe494f 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POTextField.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POTextField.kt @@ -1,41 +1,21 @@ -@file:OptIn(ExperimentalMaterial3Api::class) - package com.processout.sdk.ui.core.component.field.text -import androidx.compose.animation.animateContentSize -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.spring import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.foundation.text.selection.LocalTextSelectionColors -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.OutlinedTextFieldDefaults -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.semantics.clearAndSetSemantics -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.VisualTransformation -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi -import com.processout.sdk.ui.core.component.POText +import com.processout.sdk.ui.core.component.POMessageBox import com.processout.sdk.ui.core.component.field.POField -import com.processout.sdk.ui.core.component.field.POField.ContainerBox -import com.processout.sdk.ui.core.component.field.POField.stateStyle -import com.processout.sdk.ui.core.component.field.POField.textSelectionColors -import com.processout.sdk.ui.core.component.field.POField.textStyle -import com.processout.sdk.ui.core.extension.conditional import com.processout.sdk.ui.core.theme.ProcessOutTheme.dimensions import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing @@ -46,9 +26,11 @@ fun POTextField( value: TextFieldValue, onValueChange: (TextFieldValue) -> Unit, modifier: Modifier = Modifier, - minHeight: Dp = dimensions.formComponentMinHeight, + textFieldModifier: Modifier = Modifier, + minHeight: Dp = dimensions.fieldMinHeight, contentPadding: PaddingValues = POField.contentPadding, - style: POField.Style = POField.default, + fieldStyle: POField.Style = POField.default, + descriptionStyle: POMessageBox.Style = POMessageBox.error, enabled: Boolean = true, readOnly: Boolean = false, isDropdown: Boolean = false, @@ -56,6 +38,7 @@ fun POTextField( forceTextDirectionLtr: Boolean = false, label: String? = null, placeholder: String? = null, + description: String? = null, contentDescription: String? = null, leadingIcon: @Composable (() -> Unit)? = null, trailingIcon: @Composable (() -> Unit)? = null, @@ -67,121 +50,36 @@ fun POTextField( minLines: Int = 1, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } ) { - var isFocused by remember { mutableStateOf(false) } - val stateStyle = style.stateStyle(isError = isError, isFocused = isFocused) - CompositionLocalProvider( - LocalTextSelectionColors provides textSelectionColors(stateStyle.controlsTintColor) - ) { - BasicTextField( + Column(modifier = modifier) { + POBasicTextField( value = value, onValueChange = onValueChange, - modifier = modifier - .requiredHeightIn(min = minHeight) - .onFocusChanged { - isFocused = it.isFocused - } - .conditional(!contentDescription.isNullOrBlank()) { - if (isDropdown) { - clearAndSetSemantics { - this.contentDescription = "${value.text} $contentDescription" - } - } else { - semantics { - this.contentDescription = contentDescription ?: String() - } - } - }, + modifier = textFieldModifier.fillMaxWidth(), + minHeight = minHeight, + contentPadding = contentPadding, + style = fieldStyle, enabled = enabled, readOnly = readOnly, - textStyle = textStyle( - style = stateStyle.text, - forceTextDirectionLtr = forceTextDirectionLtr - ), - cursorBrush = SolidColor(stateStyle.controlsTintColor), + isDropdown = isDropdown, + isError = isError, + forceTextDirectionLtr = forceTextDirectionLtr, + label = label, + placeholder = placeholder, + contentDescription = contentDescription, + leadingIcon = leadingIcon, + trailingIcon = trailingIcon, + visualTransformation = visualTransformation, keyboardOptions = keyboardOptions, keyboardActions = keyboardActions, singleLine = singleLine, maxLines = maxLines, minLines = minLines, - visualTransformation = visualTransformation, - interactionSource = interactionSource, - decorationBox = @Composable { innerTextField -> - OutlinedTextFieldDefaults.DecorationBox( - value = value.text, - innerTextField = { - val animationStiffness = Spring.StiffnessMedium - Column( - modifier = Modifier.animateContentSize( - animationSpec = spring(stiffness = animationStiffness) - ) - ) { - val isLabelFloating = value.text.isNotEmpty() || (isFocused && !isDropdown) - if (!label.isNullOrBlank()) { - val fontSizeValue = stateStyle.text.textStyle.fontSize.value - val animatedFontSizeValue by animateFloatAsState( - targetValue = if (isLabelFloating) fontSizeValue * 0.8f else fontSizeValue, - animationSpec = spring(stiffness = animationStiffness) - ) - POText( - text = label, - modifier = Modifier.conditional(!contentDescription.isNullOrBlank()) { - clearAndSetSemantics { } - }, - color = stateStyle.label.color, - style = stateStyle.label.textStyle.copy(fontSize = animatedFontSizeValue.sp), - overflow = TextOverflow.Ellipsis, - maxLines = 1 - ) - if (isLabelFloating) { - Spacer(modifier = Modifier.requiredHeight(spacing.space3)) - } - } - if (isLabelFloating || label.isNullOrBlank()) { - Box { - if (value.text.isEmpty() && !placeholder.isNullOrBlank()) { - POText( - text = placeholder, - modifier = Modifier.clearAndSetSemantics {}, - color = stateStyle.placeholderTextColor, - style = stateStyle.text.textStyle, - overflow = TextOverflow.Ellipsis, - maxLines = 1 - ) - } - innerTextField() - } - } - } - }, - enabled = enabled, - isError = isError, - leadingIcon = leadingIcon, - trailingIcon = trailingIcon, - singleLine = singleLine, - visualTransformation = visualTransformation, - interactionSource = interactionSource, - contentPadding = contentPadding, - container = { - ContainerBox( - style = stateStyle, - enabled = enabled, - isDropdown = isDropdown - ) - } - ) - } + interactionSource = interactionSource ) - } -} - -@Composable -@Preview(showBackground = true) -private fun POTextFieldPreview() { - Column(modifier = Modifier.padding(16.dp)) { - POTextField( - value = TextFieldValue(text = "test@gmail.com"), - onValueChange = {}, - modifier = Modifier.fillMaxWidth() + POMessageBox( + text = description, + modifier = Modifier.padding(top = spacing.space12), + style = descriptionStyle ) } } diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POTextField2.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POTextField2.kt deleted file mode 100644 index 5abb4eb36..000000000 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/component/field/text/POTextField2.kt +++ /dev/null @@ -1,85 +0,0 @@ -package com.processout.sdk.ui.core.component.field.text - -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.text.input.VisualTransformation -import androidx.compose.ui.unit.Dp -import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi -import com.processout.sdk.ui.core.component.POMessageBox -import com.processout.sdk.ui.core.component.field.POField -import com.processout.sdk.ui.core.theme.ProcessOutTheme.dimensions -import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing - -/** @suppress */ -@ProcessOutInternalApi -@Composable -fun POTextField2( - value: TextFieldValue, - onValueChange: (TextFieldValue) -> Unit, - modifier: Modifier = Modifier, - textFieldModifier: Modifier = Modifier, - minHeight: Dp = dimensions.fieldMinHeight, - contentPadding: PaddingValues = POField.contentPadding2, - fieldStyle: POField.Style = POField.default2, - descriptionStyle: POMessageBox.Style = POMessageBox.error2, - enabled: Boolean = true, - readOnly: Boolean = false, - isDropdown: Boolean = false, - isError: Boolean = false, - forceTextDirectionLtr: Boolean = false, - label: String? = null, - placeholder: String? = null, - description: String? = null, - contentDescription: String? = null, - leadingIcon: @Composable (() -> Unit)? = null, - trailingIcon: @Composable (() -> Unit)? = null, - visualTransformation: VisualTransformation = VisualTransformation.None, - keyboardOptions: KeyboardOptions = KeyboardOptions.Default, - keyboardActions: KeyboardActions = KeyboardActions.Default, - singleLine: Boolean = true, - maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, - minLines: Int = 1, - interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } -) { - Column(modifier = modifier) { - POTextField( - value = value, - onValueChange = onValueChange, - modifier = textFieldModifier.fillMaxWidth(), - minHeight = minHeight, - contentPadding = contentPadding, - style = fieldStyle, - enabled = enabled, - readOnly = readOnly, - isDropdown = isDropdown, - isError = isError, - forceTextDirectionLtr = forceTextDirectionLtr, - label = label, - placeholder = placeholder, - contentDescription = contentDescription, - leadingIcon = leadingIcon, - trailingIcon = trailingIcon, - visualTransformation = visualTransformation, - keyboardOptions = keyboardOptions, - keyboardActions = keyboardActions, - singleLine = singleLine, - maxLines = maxLines, - minLines = minLines, - interactionSource = interactionSource - ) - POMessageBox( - text = description, - modifier = Modifier.padding(top = spacing.space12), - style = descriptionStyle - ) - } -} diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/style/PORadioButtonStyle.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/style/PORadioButtonStyle.kt index 70583ebbd..290ecd7bb 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/style/PORadioButtonStyle.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/style/PORadioButtonStyle.kt @@ -4,6 +4,7 @@ import android.os.Parcelable import androidx.annotation.ColorRes import kotlinx.parcelize.Parcelize +@Deprecated(message = "Only used in deprecated implementation.") @Parcelize data class PORadioButtonStyle( val normal: PORadioButtonStateStyle, @@ -12,6 +13,7 @@ data class PORadioButtonStyle( val disabled: PORadioButtonStateStyle? = null ) : Parcelable +@Deprecated(message = "Only used in deprecated implementation.") @Parcelize data class PORadioButtonStateStyle( @ColorRes diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Colors.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Colors.kt index ee823af44..6430e9bf8 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Colors.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Colors.kt @@ -37,11 +37,7 @@ data class POColors( @Immutable data class Input( val backgroundDefault: Color, - val backgroundDisabled: Color, val borderDefault: Color, - val borderDefault2: Color, - val borderDisabled: Color, - val borderFocused: Color, val borderError: Color ) @@ -88,7 +84,6 @@ data class POColors( val darkoutRipple: Color, val backgroundSuccess: Color, val success: Color, - val error: Color, val toastError: Color ) @@ -119,11 +114,7 @@ val POLightColorPalette = POColors( ), input = Input( backgroundDefault = Color(0xFFFFFFFF), - backgroundDisabled = Color(0x0F121314), - borderDefault = Color(0xFF7C8593), - borderDefault2 = Color(0x1F121314), - borderDisabled = Color(0xFFADB5BD), - borderFocused = Color(0xFF4791FF), + borderDefault = Color(0x1F121314), borderError = Color(0xFFBE011B) ), checkRadio = CheckRadio( @@ -162,7 +153,6 @@ val POLightColorPalette = POColors( darkoutRipple = Color(0x0F59595A), backgroundSuccess = Color(0xFF1ABE5A), success = Color(0xFFBEFAE9), - error = Color(0xFFFFC2C8), toastError = Color(0xFFFDE3DE) ), border = Border( @@ -191,11 +181,7 @@ val PODarkColorPalette = POColors( ), input = Input( backgroundDefault = Color(0xFF26292F), - backgroundDisabled = Color(0x14F6F8FB), - borderDefault = Color(0xFFCCD1D6), - borderDefault2 = Color(0x29F6F8FB), - borderDisabled = Color(0xFF7C8593), - borderFocused = Color(0xFFFFE500), + borderDefault = Color(0x29F6F8FB), borderError = Color(0xFFFF7D6C) ), checkRadio = CheckRadio( @@ -234,7 +220,6 @@ val PODarkColorPalette = POColors( darkoutRipple = Color(0x0FACADAF), backgroundSuccess = Color(0xFF28DE6B), success = Color(0xFF1DA37D), - error = Color(0xFFD11D2F), toastError = Color(0xFF511511) ), border = Border( diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/ProcessOutTheme.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/ProcessOutTheme.kt index 36f7e77ac..5b8764aa0 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/ProcessOutTheme.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/ProcessOutTheme.kt @@ -5,6 +5,7 @@ import androidx.compose.material3.ProvideTextStyle import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.ui.text.font.FontWeight import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi /** @suppress */ @@ -23,7 +24,7 @@ fun ProcessOutTheme( LocalPODimensions provides ProcessOutTheme.dimensions ) { ProvideTextStyle( - value = ProcessOutTheme.typography.body1, + value = ProcessOutTheme.typography.s16(FontWeight.Medium), content = content ) } diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Shapes.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Shapes.kt index c98a6335a..3a7a321eb 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Shapes.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Shapes.kt @@ -14,10 +14,8 @@ data class POShapes( val roundedCorners4: CornerBasedShape = RoundedCornerShape(4.dp), val roundedCorners6: CornerBasedShape = RoundedCornerShape(6.dp), val roundedCorners8: CornerBasedShape = RoundedCornerShape(8.dp), - val roundedCornersSmall: CornerBasedShape = RoundedCornerShape(4.dp), - val roundedCornersMedium: CornerBasedShape = RoundedCornerShape(8.dp), - val roundedCornersLarge: CornerBasedShape = RoundedCornerShape(16.dp), - val topRoundedCornersLarge: CornerBasedShape = RoundedCornerShape( + val roundedCorners16: CornerBasedShape = RoundedCornerShape(16.dp), + val topRoundedCorners16: CornerBasedShape = RoundedCornerShape( topStart = 16.dp, topEnd = 16.dp ) ) diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Spacing.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Spacing.kt index 118ac3050..98290aedf 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Spacing.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Spacing.kt @@ -21,12 +21,7 @@ data class POSpacing( val space16: Dp = 16.dp, val space20: Dp = 20.dp, val space28: Dp = 28.dp, - val space48: Dp = 48.dp, - val extraSmall: Dp = 4.dp, - val small: Dp = 8.dp, - val medium: Dp = 12.dp, - val large: Dp = 16.dp, - val extraLarge: Dp = 20.dp + val space48: Dp = 48.dp ) internal val LocalPOSpacing = staticCompositionLocalOf { POSpacing() } diff --git a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Typography.kt b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Typography.kt index b8eaab73b..084d44e6c 100644 --- a/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Typography.kt +++ b/ui-core/src/main/kotlin/com/processout/sdk/ui/core/theme/Typography.kt @@ -23,61 +23,7 @@ private val WorkSans = FontFamily( @ProcessOutInternalApi @Immutable data class POTypography( - val paragraph: Paragraph = Paragraph, - val title: TextStyle = TextStyle( - fontFamily = WorkSans, - fontWeight = FontWeight.Medium, - fontSize = 20.sp, - lineHeight = 24.sp - ), - val largeTitle: TextStyle = TextStyle( - fontFamily = WorkSans, - fontWeight = FontWeight.Normal, - fontSize = 28.sp, - lineHeight = 32.sp - ), - val subheading: TextStyle = TextStyle( - fontFamily = WorkSans, - fontWeight = FontWeight.Medium, - fontSize = 18.sp, - lineHeight = 24.sp - ), - val body1: TextStyle = TextStyle( - fontFamily = WorkSans, - fontWeight = FontWeight.Medium, - fontSize = 16.sp, - lineHeight = 24.sp - ), - val body2: TextStyle = TextStyle( - fontFamily = WorkSans, - fontWeight = FontWeight.Normal, - fontSize = 14.sp, - lineHeight = 18.sp - ), - val body3: TextStyle = TextStyle( - fontFamily = WorkSans, - fontWeight = FontWeight.Normal, - fontSize = 16.sp, - lineHeight = 24.sp - ), - val button: TextStyle = TextStyle( - fontFamily = WorkSans, - fontWeight = FontWeight.Medium, - fontSize = 14.sp, - lineHeight = 18.sp - ), - val label1: TextStyle = TextStyle( - fontFamily = WorkSans, - fontWeight = FontWeight.Medium, - fontSize = 14.sp, - lineHeight = 18.sp - ), - val label2: TextStyle = TextStyle( - fontFamily = WorkSans, - fontWeight = FontWeight.Normal, - fontSize = 14.sp, - lineHeight = 18.sp - ) + val paragraph: Paragraph = Paragraph ) { fun s12(fontWeight: FontWeight = FontWeight.Normal) = @@ -156,6 +102,14 @@ data class POTypography( lineHeight = 28.sp ) + fun s28(fontWeight: FontWeight = FontWeight.Normal) = + TextStyle( + fontFamily = WorkSans, + fontWeight = fontWeight, + fontSize = 28.sp, + lineHeight = 32.sp + ) + object Paragraph { fun s16(fontWeight: FontWeight = FontWeight.Normal) = diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/scanner/CardScannerScreen.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/scanner/CardScannerScreen.kt index 9dafacdeb..284d0426b 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/scanner/CardScannerScreen.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/scanner/CardScannerScreen.kt @@ -75,10 +75,10 @@ internal fun CardScannerScreen( style: CardScannerScreen.Style = CardScannerScreen.style() ) { Scaffold( - modifier = Modifier.clip(shape = shapes.topRoundedCornersLarge), + modifier = Modifier.clip(shape = shapes.topRoundedCorners16), containerColor = style.backgroundColor ) { scaffoldPadding -> - val verticalSpacingPx = (spacing.large * 2).dpToPx() + val verticalSpacingPx = (spacing.space16 * 2).dpToPx() Column( modifier = Modifier .verticalScroll( @@ -96,8 +96,8 @@ internal fun CardScannerScreen( onCheckedChange = { onEvent(TorchToggle(isEnabled = it)) }, modifier = Modifier .padding( - top = spacing.medium, - start = spacing.medium + top = spacing.space12, + start = spacing.space12 ) .requiredSizeIn( minWidth = dimensions.buttonIconSizeSmall, @@ -109,13 +109,13 @@ internal fun CardScannerScreen( ) val density = LocalDensity.current var cameraPreviewHeight by remember { mutableStateOf(0.dp) } - val cameraPreviewOffsetCorrelation = spacing.large + val cameraPreviewOffsetCorrelation = spacing.space16 Column( modifier = Modifier .padding( - start = spacing.large, - end = spacing.large, - bottom = spacing.large + start = spacing.space16, + end = spacing.space16, + bottom = spacing.space16 ) .onGloballyPositioned { with(density) { @@ -123,7 +123,7 @@ internal fun CardScannerScreen( cameraPreviewHeight = height + cameraPreviewOffsetCorrelation } }, - verticalArrangement = Arrangement.spacedBy(spacing.large), + verticalArrangement = Arrangement.spacedBy(spacing.space16), horizontalAlignment = Alignment.CenterHorizontally ) { POText( @@ -169,7 +169,7 @@ private fun CameraPreview( style: CameraPreviewStyle, cardStyle: CardStyle, modifier: Modifier = Modifier, - offsetSize: Dp = spacing.extraLarge + offsetSize: Dp = spacing.space20 ) { Box( modifier = modifier @@ -286,7 +286,7 @@ private fun ScannedCard( modifier = Modifier.conditional( condition = expiration.isBlank(), whenTrue = { requiredWidthIn(min = 88.dp) }, - whenFalse = { padding(horizontal = spacing.large) } + whenFalse = { padding(horizontal = spacing.space16) } ), color = style.expiration.color, style = style.expiration.textStyle @@ -392,7 +392,7 @@ internal object CardScannerScreen { private val defaultCameraPreview: CameraPreviewStyle @Composable get() = CameraPreviewStyle( - shape = shapes.roundedCornersMedium, + shape = shapes.roundedCorners8, border = POBorderStroke(width = 0.dp, color = Color.Transparent), overlayColor = Color.Black.copy(alpha = 0.4f) ) @@ -413,15 +413,15 @@ internal object CardScannerScreen { @Composable get() = CardStyle( number = POText.Style( color = Color.White, - textStyle = typography.largeTitle.copy(lineHeight = 28.sp) + textStyle = typography.s28().copy(lineHeight = 28.sp) ), expiration = POText.Style( color = Color.White, - textStyle = typography.body3.copy(lineHeight = 20.sp) + textStyle = typography.s16().copy(lineHeight = 20.sp) ), cardholderName = POText.Style( color = Color.White, - textStyle = typography.body3.copy(lineHeight = 20.sp) + textStyle = typography.s16().copy(lineHeight = 20.sp) ), border = POBorderStroke(width = 1.dp, color = Color.White), borderRadius = 8.dp @@ -441,7 +441,7 @@ internal object CardScannerScreen { ) private val defaultCancelButton: POButton.Style - @Composable get() = POButton.secondary2.let { + @Composable get() = POButton.secondary.let { it.copy( normal = it.normal.copy( text = it.normal.text.copy( diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/screen/CardTokenizationContent.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/screen/CardTokenizationContent.kt index 278ead7e8..a03d7d48c 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/screen/CardTokenizationContent.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/screen/CardTokenizationContent.kt @@ -27,9 +27,8 @@ import com.processout.sdk.ui.core.component.field.POField import com.processout.sdk.ui.core.component.field.checkbox.POCheckbox import com.processout.sdk.ui.core.component.field.checkbox.POCheckboxField import com.processout.sdk.ui.core.component.field.dropdown.PODropdownField -import com.processout.sdk.ui.core.component.field.dropdown.PODropdownField2 import com.processout.sdk.ui.core.component.field.radio.PORadioField -import com.processout.sdk.ui.core.component.field.text.POTextField2 +import com.processout.sdk.ui.core.component.field.text.POTextField import com.processout.sdk.ui.core.state.POActionState import com.processout.sdk.ui.core.state.POImmutableList import com.processout.sdk.ui.core.style.POAxis @@ -58,7 +57,7 @@ internal fun CardTokenizationContent( modifier = Modifier .fillMaxWidth() .requiredHeightIn(min = dimensions.buttonIconSizeSmall) - .padding(bottom = spacing.small), + .padding(bottom = spacing.space8), style = style.scanButton, iconSize = dimensions.iconSizeSmall ) @@ -97,9 +96,9 @@ private fun Section( ) { val paddingTop = when (section.id) { CARD_INFORMATION -> 0.dp - PREFERRED_SCHEME -> if (section.title == null) spacing.small else spacing.extraLarge - FUTURE_PAYMENTS -> spacing.small - else -> spacing.extraLarge + PREFERRED_SCHEME -> if (section.title == null) spacing.space8 else spacing.space20 + FUTURE_PAYMENTS -> spacing.space8 + else -> spacing.space20 } Column( modifier = Modifier @@ -108,7 +107,7 @@ private fun Section( condition = section.id == BILLING_ADDRESS, modifier = { animateContentSize() } ), - verticalArrangement = Arrangement.spacedBy(spacing.small) + verticalArrangement = Arrangement.spacedBy(spacing.space8) ) { section.title?.let { with(style.sectionTitle) { @@ -136,7 +135,7 @@ private fun Section( style = style.errorMessage, modifier = Modifier .fillMaxWidth() - .padding(top = spacing.small) + .padding(top = spacing.space8) ) var currentSubsection by remember { mutableStateOf(Section(id = String())) } currentSubsection = section.subsection ?: currentSubsection @@ -196,7 +195,7 @@ private fun Item( modifier = modifier ) is Item.Group -> Row( - horizontalArrangement = Arrangement.spacedBy(spacing.small) + horizontalArrangement = Arrangement.spacedBy(spacing.space8) ) { item.items.elements.forEach { groupItem -> Item( @@ -224,7 +223,7 @@ private fun TextField( modifier: Modifier = Modifier ) { val focusRequester = remember { FocusRequester() } - POTextField2( + POTextField( value = state.value, onValueChange = { onEvent( @@ -299,7 +298,7 @@ private fun DropdownField( menuStyle: PODropdownField.MenuStyle, modifier: Modifier = Modifier ) { - PODropdownField2( + PODropdownField( value = state.value, onValueChange = { onEvent( @@ -360,7 +359,12 @@ private fun AnimatedFieldIcon(@DrawableRes id: Int) { id = id, modifier = Modifier .requiredHeight(dimensions.formComponentMinHeight) - .padding(POField.contentPadding), + .padding( + PaddingValues( + horizontal = spacing.space16, + vertical = spacing.space12 + ) + ), contentScale = ContentScale.FillHeight ) } diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/screen/CardTokenizationScreen.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/screen/CardTokenizationScreen.kt index 436612c35..f25c01e8b 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/screen/CardTokenizationScreen.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/tokenization/screen/CardTokenizationScreen.kt @@ -46,7 +46,7 @@ internal fun CardTokenizationScreen( Scaffold( modifier = Modifier .nestedScroll(rememberNestedScrollInteropConnection()) - .clip(shape = shapes.topRoundedCornersLarge), + .clip(shape = shapes.topRoundedCorners16), containerColor = style.backgroundColor, topBar = { POHeader( @@ -80,9 +80,9 @@ internal fun CardTokenizationScreen( .fillMaxSize() .padding(scaffoldPadding) .verticalScroll(rememberScrollState()) - .padding(spacing.extraLarge) + .padding(spacing.space20) ) { - val verticalSpacingPx = (spacing.extraLarge * 4 + 15.dp).dpToPx() + val verticalSpacingPx = (spacing.space20 * 4 + 15.dp).dpToPx() CardTokenizationContent( state = state, onEvent = onEvent, @@ -153,16 +153,16 @@ internal object CardTokenizationScreen { ), field = custom?.field?.let { POField.custom(style = it) - } ?: POField.default2, + } ?: POField.default, radioField = custom?.radioField?.let { PORadioField.custom(style = it) } ?: PORadioField.default, dropdownMenu = custom?.dropdownMenu?.let { PODropdownField.custom(style = it) - } ?: PODropdownField.defaultMenu2, + } ?: PODropdownField.defaultMenu, checkbox = custom?.checkbox?.let { POCheckbox.custom(style = it) - } ?: POCheckbox.default2, + } ?: POCheckbox.default, dialog = custom?.dialog?.let { PODialog.custom(style = it) } ?: PODialog.default, @@ -177,7 +177,7 @@ internal object CardTokenizationScreen { } ?: defaultScanButton, actionsContainer = custom?.actionsContainer?.let { POActionsContainer.custom(style = it) - } ?: POActionsContainer.default2, + } ?: POActionsContainer.default, backgroundColor = custom?.backgroundColorResId?.let { colorResource(id = it) } ?: colors.surface.default, @@ -190,7 +190,7 @@ internal object CardTokenizationScreen { ) val defaultScanButton: POButton.Style - @Composable get() = POButton.secondary2.let { + @Composable get() = POButton.secondary.let { it.copy( normal = it.normal.copy( text = it.normal.text.copy( diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/card/update/CardUpdateScreen.kt b/ui/src/main/kotlin/com/processout/sdk/ui/card/update/CardUpdateScreen.kt index 42ec35b95..749333f91 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/card/update/CardUpdateScreen.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/card/update/CardUpdateScreen.kt @@ -23,7 +23,7 @@ import androidx.lifecycle.Lifecycle import com.processout.sdk.ui.card.update.CardUpdateEvent.* import com.processout.sdk.ui.core.component.* import com.processout.sdk.ui.core.component.field.POField -import com.processout.sdk.ui.core.component.field.text.POTextField2 +import com.processout.sdk.ui.core.component.field.text.POTextField import com.processout.sdk.ui.core.state.POActionState import com.processout.sdk.ui.core.state.POImmutableList import com.processout.sdk.ui.core.style.POAxis @@ -48,7 +48,7 @@ internal fun CardUpdateScreen( Scaffold( modifier = Modifier .nestedScroll(rememberNestedScrollInteropConnection()) - .clip(shape = shapes.topRoundedCornersLarge), + .clip(shape = shapes.topRoundedCorners16), containerColor = style.backgroundColor, topBar = { POHeader( @@ -82,9 +82,9 @@ internal fun CardUpdateScreen( .fillMaxSize() .padding(scaffoldPadding) .verticalScroll(rememberScrollState()) - .padding(spacing.extraLarge) + .padding(spacing.space20) ) { - val verticalSpacingPx = (spacing.extraLarge * 4 + 15.dp).dpToPx() + val verticalSpacingPx = (spacing.space20 * 4 + 15.dp).dpToPx() Column( modifier = Modifier.onGloballyPositioned { val contentHeight = it.size.height + topBarHeight + bottomBarHeight + verticalSpacingPx @@ -103,7 +103,7 @@ internal fun CardUpdateScreen( style = style.errorMessage, modifier = Modifier .fillMaxWidth() - .padding(top = spacing.small) + .padding(top = spacing.space8) ) } } @@ -119,12 +119,12 @@ private fun Fields( style: POField.Style ) { Column( - verticalArrangement = Arrangement.spacedBy(spacing.small) + verticalArrangement = Arrangement.spacedBy(spacing.space8) ) { val lifecycleEvent = rememberLifecycleEvent() fields.elements.forEach { state -> val focusRequester = remember { FocusRequester() } - POTextField2( + POTextField( value = state.value, onValueChange = { if (state.enabled) { @@ -175,7 +175,12 @@ private fun AnimatedFieldIcon(@DrawableRes id: Int) { id = id, modifier = Modifier .requiredHeight(dimensions.formComponentMinHeight) - .padding(POField.contentPadding), + .padding( + PaddingValues( + horizontal = spacing.space16, + vertical = spacing.space12 + ) + ), contentScale = ContentScale.FillHeight ) } @@ -226,7 +231,7 @@ internal object CardUpdateScreen { ), field = custom?.field?.let { POField.custom(style = it) - } ?: POField.default2, + } ?: POField.default, errorMessage = custom?.errorMessage?.let { POText.custom(style = it) } ?: POText.Style( @@ -238,7 +243,7 @@ internal object CardUpdateScreen { } ?: PODialog.default, actionsContainer = custom?.actionsContainer?.let { POActionsContainer.custom(style = it) - } ?: POActionsContainer.default2, + } ?: POActionsContainer.default, backgroundColor = custom?.backgroundColorResId?.let { colorResource(id = it) } ?: colors.surface.default, diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/checkout/DynamicCheckoutScreen.kt b/ui/src/main/kotlin/com/processout/sdk/ui/checkout/DynamicCheckoutScreen.kt index 3b1f6353c..01b271aa3 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/checkout/DynamicCheckoutScreen.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/checkout/DynamicCheckoutScreen.kt @@ -97,7 +97,7 @@ internal fun DynamicCheckoutScreen( Scaffold( modifier = Modifier .consumeWindowInsets(WindowInsets.safeDrawing) - .clip(shape = shapes.topRoundedCornersLarge), + .clip(shape = shapes.topRoundedCorners16), containerColor = animatedBackgroundColor( state = state, normalColor = style.backgroundColor, @@ -166,12 +166,12 @@ private fun Content( Column( modifier = Modifier .fillMaxSize() - .padding(spacing.extraLarge) + .padding(spacing.space20) ) { POMessageBox( text = state.errorMessage, style = style.errorMessageBox, - modifier = Modifier.padding(bottom = spacing.large), + modifier = Modifier.padding(bottom = spacing.space16), horizontalArrangement = Arrangement.spacedBy(RowComponentSpacing), enterAnimationDelayMillis = ShortAnimationDurationMillis ) @@ -222,7 +222,7 @@ private fun ExpressCheckoutHeader( ) { Row( modifier = Modifier - .padding(bottom = spacing.large) + .padding(bottom = spacing.space16) .fillMaxWidth() .requiredHeightIn(min = dimensions.buttonIconSizeSmall), horizontalArrangement = Arrangement.SpaceBetween, @@ -246,7 +246,7 @@ private fun ExpressCheckoutHeader( ) }, modifier = Modifier - .padding(start = spacing.small) + .padding(start = spacing.space8) .requiredSizeIn( minWidth = dimensions.buttonIconSizeSmall, minHeight = dimensions.buttonIconSizeSmall @@ -267,8 +267,8 @@ private fun ExpressPayments( isLightTheme: Boolean ) { Column( - modifier = Modifier.padding(bottom = spacing.extraLarge), - verticalArrangement = Arrangement.spacedBy(spacing.small) + modifier = Modifier.padding(bottom = spacing.space20), + verticalArrangement = Arrangement.spacedBy(spacing.space8) ) { payments.elements.forEach { payment -> when (payment) { @@ -348,7 +348,7 @@ private fun ExpressPayment( PaymentLogo( logoResource = payment.logoResource, fallbackBoxColor = Color.Transparent, - modifier = Modifier.padding(end = spacing.small), + modifier = Modifier.padding(end = spacing.space8), isLightTheme = isLightTheme ) } @@ -416,8 +416,8 @@ private fun RegularPayment( ) .fillMaxWidth() .padding( - horizontal = spacing.extraLarge, - vertical = spacing.small + horizontal = spacing.space20, + vertical = spacing.space8 ), horizontalArrangement = Arrangement.spacedBy(RowComponentSpacing), verticalAlignment = Alignment.CenterVertically @@ -467,9 +467,9 @@ private fun RegularPaymentContent( .animateContentSize() .fillMaxWidth() .padding( - start = spacing.extraLarge, - end = spacing.extraLarge, - bottom = spacing.extraLarge + start = spacing.space20, + end = spacing.space20, + bottom = spacing.space20 ) ) { payment.state.description?.let { @@ -532,7 +532,7 @@ private fun RegularPaymentContent( ) }, modifier = Modifier - .padding(top = spacing.extraLarge) + .padding(top = spacing.space20) .fillMaxWidth() .requiredHeightIn(min = dimensions.interactiveComponentMinSize), style = style.actionsContainer.primary, @@ -554,7 +554,7 @@ private fun AlternativePayment( style: DynamicCheckoutScreen.Style ) { Column( - modifier = Modifier.padding(top = spacing.small) + modifier = Modifier.padding(top = spacing.space8) ) { when (state.savePaymentMethodField) { is CheckboxField -> CheckboxField( @@ -622,7 +622,7 @@ private fun PaymentLogo( .requiredSize(PaymentLogoSize) .background( color = fallbackBoxColor, - shape = shapes.roundedCornersSmall + shape = shapes.roundedCorners4 ) ) } @@ -667,8 +667,8 @@ private fun Success( Column( modifier = Modifier .fillMaxWidth() - .padding(top = spacing.extraLarge * 2), - verticalArrangement = Arrangement.spacedBy(spacing.extraLarge), + .padding(top = spacing.space20 * 2), + verticalArrangement = Arrangement.spacedBy(spacing.space20), horizontalAlignment = Alignment.CenterHorizontally ) { POText( @@ -814,19 +814,19 @@ internal object DynamicCheckoutScreen { } ?: POGroupedContent.default, field = custom?.field?.let { POField.custom(style = it) - } ?: POField.default2, + } ?: POField.default, codeField = custom?.codeField?.let { POField.custom(style = it) - } ?: POCodeField.default2, + } ?: POCodeField.default, radioField = custom?.radioField?.let { PORadioField.custom(style = it) } ?: PORadioField.default, checkbox = custom?.checkbox?.let { POCheckbox.custom(style = it) - } ?: POCheckbox.default2, + } ?: POCheckbox.default, dropdownMenu = custom?.dropdownMenu?.let { PODropdownField.custom(style = it) - } ?: PODropdownField.defaultMenu2, + } ?: PODropdownField.defaultMenu, bodyText = custom?.bodyText?.let { style -> val controlsTintColor = custom.controlsTintColorResId?.let { colorResource(id = it) } AndroidTextView.custom( @@ -842,7 +842,7 @@ internal object DynamicCheckoutScreen { ), errorMessageBox = custom?.errorMessageBox?.let { POMessageBox.custom(style = it) - } ?: POMessageBox.error2, + } ?: POMessageBox.error, dialog = custom?.dialog?.let { PODialog.custom(style = it) } ?: PODialog.default, @@ -854,7 +854,7 @@ internal object DynamicCheckoutScreen { } ?: CardTokenizationScreen.defaultScanButton, actionsContainer = custom?.actionsContainer?.let { POActionsContainer.custom(style = it) - } ?: POActionsContainer.default2, + } ?: POActionsContainer.default, backgroundColor = custom?.backgroundColorResId?.let { colorResource(id = it) } ?: colors.surface.default, @@ -866,7 +866,10 @@ internal object DynamicCheckoutScreen { private val defaultSectionHeader: SectionHeaderStyle @Composable get() = SectionHeaderStyle( - title = POText.subheading, + title = POText.Style( + color = colors.text.primary, + textStyle = typography.s18(FontWeight.Medium) + ), trailingButton = POButton.ghostEqualPadding ) @@ -884,13 +887,16 @@ internal object DynamicCheckoutScreen { textStyle = typography.s14() ) return RegularPaymentStyle( - title = POText.body1, + title = POText.Style( + color = colors.text.primary, + textStyle = typography.s16(FontWeight.Medium) + ), description = POTextWithIcon.Style( text = description, iconResId = R.drawable.po_icon_warning_diamond, iconColorFilter = ColorFilter.tint(color = description.color) ), - shape = shapes.roundedCornersSmall, + shape = shapes.roundedCorners4, border = POBorderStroke(width = 1.dp, color = colors.border.border4), backgroundColor = colors.surface.default ) @@ -926,7 +932,7 @@ internal object DynamicCheckoutScreen { @Composable get() = PaymentSuccessStyle( message = POText.Style( color = colors.text.success, - textStyle = typography.body1 + textStyle = typography.s16(FontWeight.Medium) ), successImageResId = com.processout.sdk.ui.R.drawable.po_success_image, backgroundColor = colors.surface.success diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/napm/screen/NativeAlternativePaymentContent.kt b/ui/src/main/kotlin/com/processout/sdk/ui/napm/screen/NativeAlternativePaymentContent.kt index 9dc62ac22..b9828c1f0 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/napm/screen/NativeAlternativePaymentContent.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/napm/screen/NativeAlternativePaymentContent.kt @@ -24,12 +24,10 @@ import com.processout.sdk.ui.core.component.field.POField import com.processout.sdk.ui.core.component.field.checkbox.POCheckbox import com.processout.sdk.ui.core.component.field.checkbox.POCheckboxField import com.processout.sdk.ui.core.component.field.code.POCodeField -import com.processout.sdk.ui.core.component.field.code.POCodeField2 import com.processout.sdk.ui.core.component.field.dropdown.PODropdownField -import com.processout.sdk.ui.core.component.field.dropdown.PODropdownField2 import com.processout.sdk.ui.core.component.field.phone.POPhoneNumberField import com.processout.sdk.ui.core.component.field.radio.PORadioField -import com.processout.sdk.ui.core.component.field.text.POTextField2 +import com.processout.sdk.ui.core.component.field.text.POTextField import com.processout.sdk.ui.core.component.stepper.POVerticalStepper import com.processout.sdk.ui.core.shared.image.POImageRenderingMode.ORIGINAL import com.processout.sdk.ui.core.shared.image.POImageRenderingMode.TEMPLATE @@ -289,7 +287,7 @@ private fun TextField( modifier: Modifier = Modifier ) { val focusRequester = remember { FocusRequester() } - POTextField2( + POTextField( value = state.value, onValueChange = { onEvent( @@ -343,7 +341,7 @@ private fun CodeField( descriptionStyle: POMessageBox.Style, modifier: Modifier = Modifier ) { - POCodeField2( + POCodeField( value = state.value, onValueChange = { onEvent( @@ -420,7 +418,7 @@ private fun DropdownField( descriptionStyle: POMessageBox.Style, modifier: Modifier = Modifier ) { - PODropdownField2( + PODropdownField( value = state.value, onValueChange = { onEvent( diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/napm/screen/NativeAlternativePaymentScreen.kt b/ui/src/main/kotlin/com/processout/sdk/ui/napm/screen/NativeAlternativePaymentScreen.kt index e074d852e..14ba1312b 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/napm/screen/NativeAlternativePaymentScreen.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/napm/screen/NativeAlternativePaymentScreen.kt @@ -42,7 +42,6 @@ import com.processout.sdk.ui.core.component.stepper.POStepper import com.processout.sdk.ui.core.state.POActionState import com.processout.sdk.ui.core.state.POImmutableList import com.processout.sdk.ui.core.style.POAxis -import com.processout.sdk.ui.core.theme.ProcessOutTheme import com.processout.sdk.ui.core.theme.ProcessOutTheme.colors import com.processout.sdk.ui.core.theme.ProcessOutTheme.shapes import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing @@ -79,7 +78,7 @@ internal fun NativeAlternativePaymentScreen( Scaffold( modifier = Modifier .nestedScroll(rememberNestedScrollInteropConnection()) - .clip(shape = shapes.topRoundedCornersLarge), + .clip(shape = shapes.topRoundedCorners16), containerColor = style.backgroundColor, topBar = { Header( @@ -310,75 +309,73 @@ internal object NativeAlternativePaymentScreen { @Composable fun style(custom: PONativeAlternativePaymentConfiguration.Style? = null) = - with(ProcessOutTheme) { - Style( - title = custom?.title?.let { - POText.custom(style = it) - } ?: POText.Style( - color = colors.text.primary, - textStyle = typography.s20(FontWeight.Medium) - ), - bodyText = custom?.bodyText?.let { style -> - val controlsTintColor = custom.controlsTintColorResId?.let { colorResource(id = it) } - AndroidTextView.custom( - style = style, - controlsTintColor = controlsTintColor ?: colors.text.primary - ) - } ?: AndroidTextView.default, - message = custom?.message?.let { - POText.custom(style = it) - } ?: POText.Style( - color = colors.text.secondary, - textStyle = typography.s14() - ), - labeledContent = custom?.labeledContent?.let { - POLabeledContent.custom(style = it) - } ?: POLabeledContent.default, - groupedContent = custom?.groupedContent?.let { - POGroupedContent.custom(style = it) - } ?: POGroupedContent.default, - field = custom?.field?.let { - POField.custom(style = it) - } ?: POField.default2, - codeField = custom?.codeField?.let { - POField.custom(style = it) - } ?: POCodeField.default2, - radioField = custom?.radioField?.let { - PORadioField.custom(style = it) - } ?: PORadioField.default, - dropdownMenu = custom?.dropdownMenu?.let { - PODropdownField.custom(style = it) - } ?: PODropdownField.defaultMenu2, - checkbox = custom?.checkbox?.let { - POCheckbox.custom(style = it) - } ?: POCheckbox.default2, - dialog = custom?.dialog?.let { - PODialog.custom(style = it) - } ?: PODialog.default, - stepper = custom?.stepper?.let { - POStepper.custom(style = it) - } ?: POStepper.default, - success = custom?.success?.custom() ?: defaultSuccess, - errorMessageBox = custom?.errorMessageBox?.let { - POMessageBox.custom(style = it) - } ?: POMessageBox.error2, - actionsContainer = custom?.actionsContainer?.let { - POActionsContainer.custom(style = it) - } ?: POActionsContainer.default2, - backgroundColor = custom?.backgroundColorResId?.let { - colorResource(id = it) - } ?: colors.surface.default, - progressIndicatorColor = custom?.progressIndicatorColorResId?.let { - colorResource(id = it) - } ?: colors.button.primaryBackgroundDefault, - dividerColor = custom?.dividerColorResId?.let { - colorResource(id = it) - } ?: colors.border.border4, - dragHandleColor = custom?.dragHandleColorResId?.let { - colorResource(id = it) - } ?: colors.icon.disabled - ) - } + Style( + title = custom?.title?.let { + POText.custom(style = it) + } ?: POText.Style( + color = colors.text.primary, + textStyle = typography.s20(FontWeight.Medium) + ), + bodyText = custom?.bodyText?.let { style -> + val controlsTintColor = custom.controlsTintColorResId?.let { colorResource(id = it) } + AndroidTextView.custom( + style = style, + controlsTintColor = controlsTintColor ?: colors.text.primary + ) + } ?: AndroidTextView.default, + message = custom?.message?.let { + POText.custom(style = it) + } ?: POText.Style( + color = colors.text.secondary, + textStyle = typography.s14() + ), + labeledContent = custom?.labeledContent?.let { + POLabeledContent.custom(style = it) + } ?: POLabeledContent.default, + groupedContent = custom?.groupedContent?.let { + POGroupedContent.custom(style = it) + } ?: POGroupedContent.default, + field = custom?.field?.let { + POField.custom(style = it) + } ?: POField.default, + codeField = custom?.codeField?.let { + POField.custom(style = it) + } ?: POCodeField.default, + radioField = custom?.radioField?.let { + PORadioField.custom(style = it) + } ?: PORadioField.default, + dropdownMenu = custom?.dropdownMenu?.let { + PODropdownField.custom(style = it) + } ?: PODropdownField.defaultMenu, + checkbox = custom?.checkbox?.let { + POCheckbox.custom(style = it) + } ?: POCheckbox.default, + dialog = custom?.dialog?.let { + PODialog.custom(style = it) + } ?: PODialog.default, + stepper = custom?.stepper?.let { + POStepper.custom(style = it) + } ?: POStepper.default, + success = custom?.success?.custom() ?: defaultSuccess, + errorMessageBox = custom?.errorMessageBox?.let { + POMessageBox.custom(style = it) + } ?: POMessageBox.error, + actionsContainer = custom?.actionsContainer?.let { + POActionsContainer.custom(style = it) + } ?: POActionsContainer.default, + backgroundColor = custom?.backgroundColorResId?.let { + colorResource(id = it) + } ?: colors.surface.default, + progressIndicatorColor = custom?.progressIndicatorColorResId?.let { + colorResource(id = it) + } ?: colors.button.primaryBackgroundDefault, + dividerColor = custom?.dividerColorResId?.let { + colorResource(id = it) + } ?: colors.border.border4, + dragHandleColor = custom?.dragHandleColorResId?.let { + colorResource(id = it) + } ?: colors.icon.disabled + ) val defaultSuccess: SuccessStyle @Composable get() = SuccessStyle( diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/savedpaymentmethods/SavedPaymentMethodsScreen.kt b/ui/src/main/kotlin/com/processout/sdk/ui/savedpaymentmethods/SavedPaymentMethodsScreen.kt index 4656824fc..51c5b9e0b 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/savedpaymentmethods/SavedPaymentMethodsScreen.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/savedpaymentmethods/SavedPaymentMethodsScreen.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.rememberNestedScrollInteropConnection import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @@ -58,7 +59,7 @@ internal fun SavedPaymentMethodsScreen( Scaffold( modifier = Modifier .nestedScroll(rememberNestedScrollInteropConnection()) - .clip(shape = shapes.topRoundedCornersLarge), + .clip(shape = shapes.topRoundedCorners16), containerColor = style.backgroundColor, topBar = { Header( @@ -93,11 +94,11 @@ internal fun SavedPaymentMethodsScreen( .fillMaxSize() .padding(scaffoldPadding) .verticalScroll(rememberScrollState()) - .padding(spacing.extraLarge), + .padding(spacing.space20), verticalArrangement = if (content is Loaded) Arrangement.Top else Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { - val verticalSpacingPx = (spacing.extraLarge * 4 + spacing.small).dpToPx() + val verticalSpacingPx = (spacing.space20 * 4 + spacing.space8).dpToPx() Column( modifier = Modifier.onGloballyPositioned { val contentHeight = it.size.height + topBarHeight + verticalSpacingPx @@ -175,7 +176,7 @@ private fun Content( POMessageBox( text = state.errorMessage, style = style.messageBox, - modifier = Modifier.padding(bottom = spacing.extraLarge), + modifier = Modifier.padding(bottom = spacing.space20), horizontalArrangement = Arrangement.spacedBy(RowComponentSpacing) ) val borderWidth = style.paymentMethod.border.width @@ -220,10 +221,10 @@ private fun PaymentMethod( modifier = Modifier .fillMaxWidth() .padding( - start = spacing.extraLarge, - end = spacing.medium, - top = spacing.large, - bottom = spacing.large + start = spacing.space20, + end = spacing.space12, + top = spacing.space16, + bottom = spacing.space16 ), horizontalArrangement = Arrangement.spacedBy(RowComponentSpacing), verticalAlignment = Alignment.CenterVertically @@ -293,7 +294,7 @@ private fun PaymentLogo( .requiredSize(PaymentLogoSize) .background( color = fallbackBoxColor, - shape = shapes.roundedCornersSmall + shape = shapes.roundedCorners4 ) ) } @@ -306,7 +307,7 @@ private fun Empty( ) { Column( verticalArrangement = Arrangement.spacedBy( - space = spacing.medium, + space = spacing.space12, alignment = Alignment.CenterVertically ), horizontalAlignment = Alignment.CenterHorizontally @@ -315,7 +316,7 @@ private fun Empty( painter = painterResource(id = R.drawable.po_card_credit), contentDescription = null, modifier = Modifier - .padding(bottom = spacing.small) + .padding(bottom = spacing.space8) .requiredSize(EmptyContentImageSize) ) POText( @@ -387,10 +388,13 @@ internal object SavedPaymentMethodsScreen { colorResource(id = it) } ?: colors.button.primaryBackgroundDefault, emptyContentStyle = EmptyContentStyle( - message = POText.body1, + message = POText.Style( + color = colors.text.primary, + textStyle = typography.s16(FontWeight.Medium) + ), description = POText.Style( color = colors.text.muted, - textStyle = typography.body2 + textStyle = typography.s14() ) ), backgroundColor = custom?.backgroundColorResId?.let { @@ -400,7 +404,10 @@ internal object SavedPaymentMethodsScreen { private val defaultHeader: HeaderStyle @Composable get() = HeaderStyle( - title = POText.title, + title = POText.Style( + color = colors.text.primary, + textStyle = typography.s20(FontWeight.Medium) + ), dragHandleColor = colors.icon.disabled, dividerColor = colors.border.border4, backgroundColor = colors.surface.default @@ -423,9 +430,12 @@ internal object SavedPaymentMethodsScreen { private val defaultPaymentMethod: PaymentMethodStyle @Composable get() = PaymentMethodStyle( - description = POText.body1, + description = POText.Style( + color = colors.text.primary, + textStyle = typography.s16(FontWeight.Medium) + ), deleteButton = POButton.ghostEqualPadding, - shape = shapes.roundedCornersSmall, + shape = shapes.roundedCorners4, border = POBorderStroke(width = 1.dp, color = colors.border.border4), backgroundColor = colors.surface.default ) diff --git a/ui/src/main/kotlin/com/processout/sdk/ui/shared/component/AndroidTextView.kt b/ui/src/main/kotlin/com/processout/sdk/ui/shared/component/AndroidTextView.kt index 7fff7391d..7cf402e1e 100644 --- a/ui/src/main/kotlin/com/processout/sdk/ui/shared/component/AndroidTextView.kt +++ b/ui/src/main/kotlin/com/processout/sdk/ui/shared/component/AndroidTextView.kt @@ -30,7 +30,8 @@ import com.processout.sdk.ui.core.style.POTextStyle import com.processout.sdk.ui.core.style.POTextType import com.processout.sdk.ui.core.style.POTextType.Weight import com.processout.sdk.ui.core.style.POTextType.Weight.* -import com.processout.sdk.ui.core.theme.ProcessOutTheme +import com.processout.sdk.ui.core.theme.ProcessOutTheme.colors +import com.processout.sdk.ui.core.theme.ProcessOutTheme.typography import com.processout.sdk.ui.shared.component.AndroidTextView.apply import com.processout.sdk.ui.shared.extension.spToPx import com.processout.sdk.ui.shared.view.extension.POTextViewExtensions.setMarkdown @@ -80,20 +81,18 @@ internal object AndroidTextView { ) val default: Style - @Composable get() = with(ProcessOutTheme) { - Style( - type = with(typography.paragraph.s16(FontWeight.Medium)) { - POTextType( - textSizeSp = fontSize.value.toInt(), - lineHeightSp = lineHeight.value.toInt(), - fontResId = R.font.work_sans_medium, - weight = MEDIUM - ) - }, - color = colors.text.primary, - controlsTintColor = colors.text.primary - ) - } + @Composable get() = Style( + type = with(typography.paragraph.s16(FontWeight.Medium)) { + POTextType( + textSizeSp = fontSize.value.toInt(), + lineHeightSp = lineHeight.value.toInt(), + fontResId = R.font.work_sans_medium, + weight = MEDIUM + ) + }, + color = colors.text.primary, + controlsTintColor = colors.text.primary + ) @Composable fun custom(