From cdbd3604cd0a72816ae3ac1ae003deae25b2f165 Mon Sep 17 00:00:00 2001 From: Skyler Reimer Date: Wed, 23 Mar 2022 16:50:16 -0700 Subject: [PATCH 1/5] add public api for project wardrobe --- .../stripe/android/ui/core/PaymentsTheme.kt | 215 ++---------------- paymentsheet/api/paymentsheet.api | 136 ++++++++++- .../res/font/roboto.ttf | Bin .../BasePaymentMethodsListFragment.kt | 51 +++-- .../paymentsheet/PaymentOptionsActivity.kt | 13 +- .../android/paymentsheet/PaymentSheet.kt | 176 +++++++++++++- .../paymentsheet/PaymentSheetActivity.kt | 29 +-- .../PaymentSheetConfigurationKtx.kt | 130 +++++++++++ .../paymentsheet/ui/BaseSheetActivity.kt | 17 +- .../android/paymentsheet/ui/PrimaryButton.kt | 10 +- .../paymentsheet/GooglePayButtonTest.kt | 1 + .../PaymentOptionsActivityTest.kt | 1 + ...mentOptionsAddPaymentMethodFragmentTest.kt | 1 + 13 files changed, 523 insertions(+), 257 deletions(-) rename {payments-ui-core => paymentsheet}/res/font/roboto.ttf (100%) diff --git a/payments-ui-core/src/main/java/com/stripe/android/ui/core/PaymentsTheme.kt b/payments-ui-core/src/main/java/com/stripe/android/ui/core/PaymentsTheme.kt index 0e96deab3d2..11560275479 100644 --- a/payments-ui-core/src/main/java/com/stripe/android/ui/core/PaymentsTheme.kt +++ b/payments-ui-core/src/main/java/com/stripe/android/ui/core/PaymentsTheme.kt @@ -6,153 +6,16 @@ import android.content.res.Configuration.UI_MODE_NIGHT_YES import androidx.annotation.RestrictTo import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Colors import androidx.compose.material.MaterialTheme import androidx.compose.material.Shapes import androidx.compose.material.Typography -import androidx.compose.material.lightColors import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.Font -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp - -@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) -data class PaymentsColors( - val primary: Color, - val surface: Color, - val componentBackground: Color, - val componentBorder: Color, - val componentDivider: Color, - val onPrimary: Color, - val textSecondary: Color, - val textCursor: Color, - val placeholderText: Color, - val onBackground: Color, - val appBarIcon: Color, - val error: Color, -) - -@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) -object PaymentsThemeConfig { - fun colors(isDark: Boolean): PaymentsColors { - return if (isDark) colorsDark else colorsLight - } - - @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) - object Shapes { - val cornerRadius = 6.dp - val borderStrokeWidth = 1.dp - val borderStrokeWidthSelected = 2.dp - } - - @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) - object Typography { - private val fontWeightBold: Int = FontWeight.Bold.weight - private val fontWeightMedium: Int = FontWeight.Medium.weight - private val fontWeightNormal: Int = FontWeight.Normal.weight - private val fontSizeMultiplier: Float = 1.0F - val fontFamily: Int = R.font.roboto - - // h4 is our largest headline. It is used for the most important labels in our UI - // ex: "Select your payment method" in Payment Sheet. - val h4 = TextStyle.Default.copy( - fontFamily = FontFamily(Font(fontFamily)), - fontSize = (20.0 * fontSizeMultiplier).sp, - fontWeight = FontWeight(fontWeightBold), - ) - - // h5 is our medium headline label. - // ex: "Pay $50.99" in Payment Sheet's buy button. - val h5 = TextStyle.Default.copy( - fontFamily = FontFamily(Font(fontFamily)), - fontSize = (16.0 * fontSizeMultiplier).sp, - fontWeight = FontWeight(fontWeightMedium), - letterSpacing = (-0.32).sp - ) - - // h6 is our smallest headline label. - // ex: Section labels in Payment Sheet - val h6 = TextStyle.Default.copy( - fontFamily = FontFamily(Font(fontFamily)), - fontSize = (13.0 * fontSizeMultiplier).sp, - fontWeight = FontWeight(fontWeightMedium), - letterSpacing = (-0.15).sp - ) - - // body1 is our larger body text. Used for the bulk of our elements and forms. - // ex: the text used in Payment Sheet's text form elements. - val body1 = TextStyle.Default.copy( - fontFamily = FontFamily(Font(fontFamily)), - fontSize = (14.0 * fontSizeMultiplier).sp, - fontWeight = FontWeight(fontWeightNormal), - ) - - // subtitle1 is our only subtitle size. Used for labeling fields. - // ex: the placeholder texts that appear when you type in Payment Sheet's forms. - val subtitle1 = TextStyle.Default.copy( - fontFamily = FontFamily(Font(fontFamily)), - fontSize = (14.0 * fontSizeMultiplier).sp, - fontWeight = FontWeight(fontWeightNormal), - letterSpacing = (-0.15).sp - ) - - // caption is used to label images in payment sheet. - // ex: the labels under our payment method selectors in Payment Sheet. - val caption = TextStyle.Default.copy( - fontFamily = FontFamily(Font(fontFamily)), - fontSize = (12.0 * fontSizeMultiplier).sp, - fontWeight = FontWeight(fontWeightMedium) - ) - - // body2 is our smaller body text. Used for less important fields that are not required to - // read. Ex: our mandate texts in Payment Sheet. - val body2 = TextStyle.Default.copy( - fontFamily = FontFamily(Font(fontFamily)), - fontSize = (9.0 * fontSizeMultiplier).sp, - fontWeight = FontWeight(fontWeightNormal), - letterSpacing = (-0.15).sp - ) - } - - private val colorsLight = PaymentsColors( - primary = Color(0xFF007AFF), - surface = Color.White, - componentBackground = Color.White, - componentBorder = Color(0x33787880), - componentDivider = Color(0x33787880), - onPrimary = Color.Black, - textSecondary = Color(0x99000000), - textCursor = Color.Black, - placeholderText = Color(0x993C3C43), - onBackground = Color.Black, - appBarIcon = Color(0x99000000), - error = Color.Red, - ) - - private val colorsDark = PaymentsColors( - primary = Color(0xFF0074D4), - surface = Color(0xff2e2e2e), - componentBackground = Color.DarkGray, - componentBorder = Color(0xFF787880), - componentDivider = Color(0xFF787880), - onPrimary = Color.White, - textSecondary = Color(0x99FFFFFF), - textCursor = Color.White, - placeholderText = Color(0x61FFFFFF), - onBackground = Color.White, - appBarIcon = Color.White, - error = Color.Red, - ) -} @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) data class PaymentsComposeColors( @@ -172,67 +35,15 @@ data class PaymentsComposeShapes( val material: Shapes ) -@Composable -@ReadOnlyComposable -@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) -fun PaymentsThemeConfig.toComposeColors(): PaymentsComposeColors { - val colors = colors(isSystemInDarkTheme()) - return PaymentsComposeColors( - colorComponentBackground = colors.componentBackground, - colorComponentBorder = colors.componentBorder, - colorComponentDivider = colors.componentDivider, - colorTextSecondary = colors.textSecondary, - colorTextCursor = colors.textCursor, - placeholderText = colors.placeholderText, - - material = lightColors( - primary = colors.primary, - onPrimary = colors.onPrimary, - surface = colors.surface, - onBackground = colors.onBackground, - error = colors.error, - ) - ) -} - -@Composable -@ReadOnlyComposable -@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) -fun PaymentsThemeConfig.Shapes.toComposeShapes(): PaymentsComposeShapes { - return PaymentsComposeShapes( - borderStrokeWidth = borderStrokeWidth, - borderStrokeWidthSelected = borderStrokeWidthSelected, - material = MaterialTheme.shapes.copy( - small = RoundedCornerShape(cornerRadius), - medium = RoundedCornerShape(cornerRadius) - ) - ) -} - -@Composable -@ReadOnlyComposable -@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) -fun PaymentsThemeConfig.Typography.toComposeTypography(): Typography { - return MaterialTheme.typography.copy( - body1 = body1, - body2 = body2, - h4 = h4, - h5 = h5, - h6 = h6, - subtitle1 = subtitle1, - caption = caption - ) -} - @Composable @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) fun PaymentsTheme( content: @Composable () -> Unit ) { - val colors = PaymentsThemeConfig.toComposeColors() + val colors = PaymentsTheme.colors val localColors = staticCompositionLocalOf { colors } - val shapes = PaymentsThemeConfig.Shapes.toComposeShapes() + val shapes = PaymentsTheme.shapes val localShapes = staticCompositionLocalOf { shapes } CompositionLocalProvider( @@ -241,7 +52,7 @@ fun PaymentsTheme( ) { MaterialTheme( colors = PaymentsTheme.colors.material, - typography = PaymentsThemeConfig.Typography.toComposeTypography(), + typography = PaymentsTheme.typography, shapes = PaymentsTheme.shapes.material, content = content ) @@ -253,20 +64,22 @@ fun PaymentsTheme( // This mirrors an object that lives inside of MaterialTheme. @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) object PaymentsTheme { + lateinit var colorsLight: PaymentsComposeColors + lateinit var colorsDark: PaymentsComposeColors val colors: PaymentsComposeColors @Composable @ReadOnlyComposable - get() = PaymentsThemeConfig.toComposeColors() + get() = if (isSystemInDarkTheme()) colorsDark else colorsLight - val shapes: PaymentsComposeShapes - @Composable - @ReadOnlyComposable - get() = PaymentsThemeConfig.Shapes.toComposeShapes() + lateinit var shapes: PaymentsComposeShapes - val typography: Typography - @Composable - @ReadOnlyComposable - get() = PaymentsThemeConfig.Typography.toComposeTypography() + lateinit var typography: Typography + const val xxsmallFont = 9.0 + const val xsmallFont = 12.0 + const val smallFont = 13.0 + const val mediumFont = 14.0 + const val largeFont = 16.0 + const val extraLargeFont = 20.0 @Composable @ReadOnlyComposable diff --git a/paymentsheet/api/paymentsheet.api b/paymentsheet/api/paymentsheet.api index 5b42ef79631..0f107d9a5a2 100644 --- a/paymentsheet/api/paymentsheet.api +++ b/paymentsheet/api/paymentsheet.api @@ -76,6 +76,39 @@ public final class com/stripe/android/paymentsheet/PaymentSheet$Address$Builder public final fun state (Ljava/lang/String;)Lcom/stripe/android/paymentsheet/PaymentSheet$Address$Builder; } +public final class com/stripe/android/paymentsheet/PaymentSheet$Appearance : android/os/Parcelable { + public static final field $stable I + public static final field CREATOR Landroid/os/Parcelable$Creator; + public fun ()V + public fun (Lcom/stripe/android/paymentsheet/PaymentSheet$Colors;Lcom/stripe/android/paymentsheet/PaymentSheet$Colors;Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes;Lcom/stripe/android/paymentsheet/PaymentSheet$Typography;)V + public synthetic fun (Lcom/stripe/android/paymentsheet/PaymentSheet$Colors;Lcom/stripe/android/paymentsheet/PaymentSheet$Colors;Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes;Lcom/stripe/android/paymentsheet/PaymentSheet$Typography;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lcom/stripe/android/paymentsheet/PaymentSheet$Colors; + public final fun component2 ()Lcom/stripe/android/paymentsheet/PaymentSheet$Colors; + public final fun component3 ()Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes; + public final fun component4 ()Lcom/stripe/android/paymentsheet/PaymentSheet$Typography; + public final fun copy (Lcom/stripe/android/paymentsheet/PaymentSheet$Colors;Lcom/stripe/android/paymentsheet/PaymentSheet$Colors;Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes;Lcom/stripe/android/paymentsheet/PaymentSheet$Typography;)Lcom/stripe/android/paymentsheet/PaymentSheet$Appearance; + public static synthetic fun copy$default (Lcom/stripe/android/paymentsheet/PaymentSheet$Appearance;Lcom/stripe/android/paymentsheet/PaymentSheet$Colors;Lcom/stripe/android/paymentsheet/PaymentSheet$Colors;Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes;Lcom/stripe/android/paymentsheet/PaymentSheet$Typography;ILjava/lang/Object;)Lcom/stripe/android/paymentsheet/PaymentSheet$Appearance; + public fun describeContents ()I + public fun equals (Ljava/lang/Object;)Z + public final fun getColors (Z)Lcom/stripe/android/paymentsheet/PaymentSheet$Colors; + public final fun getColorsDark ()Lcom/stripe/android/paymentsheet/PaymentSheet$Colors; + public final fun getColorsLight ()Lcom/stripe/android/paymentsheet/PaymentSheet$Colors; + public final fun getShapes ()Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes; + public final fun getTypography ()Lcom/stripe/android/paymentsheet/PaymentSheet$Typography; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; + public fun writeToParcel (Landroid/os/Parcel;I)V +} + +public final class com/stripe/android/paymentsheet/PaymentSheet$Appearance$Builder { + public static final field $stable I + public fun ()V + public final fun colorsDark (Lcom/stripe/android/paymentsheet/PaymentSheet$Colors;)Lcom/stripe/android/paymentsheet/PaymentSheet$Appearance$Builder; + public final fun colorsLight (Lcom/stripe/android/paymentsheet/PaymentSheet$Colors;)Lcom/stripe/android/paymentsheet/PaymentSheet$Appearance$Builder; + public final fun shapes (Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes;)Lcom/stripe/android/paymentsheet/PaymentSheet$Appearance$Builder; + public final fun typography (Lcom/stripe/android/paymentsheet/PaymentSheet$Typography;)Lcom/stripe/android/paymentsheet/PaymentSheet$Appearance$Builder; +} + public final class com/stripe/android/paymentsheet/PaymentSheet$BillingDetails : android/os/Parcelable { public static final field $stable I public static final field CREATOR Landroid/os/Parcelable$Creator; @@ -110,6 +143,47 @@ public final class com/stripe/android/paymentsheet/PaymentSheet$BillingDetails$B public final fun phone (Ljava/lang/String;)Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails$Builder; } +public final class com/stripe/android/paymentsheet/PaymentSheet$Colors : android/os/Parcelable { + public static final field $stable I + public static final field CREATOR Landroid/os/Parcelable$Creator; + public static final field Companion Lcom/stripe/android/paymentsheet/PaymentSheet$Colors$Companion; + public fun (IIIIIIIIIII)V + public final fun component1 ()I + public final fun component10 ()I + public final fun component11 ()I + public final fun component2 ()I + public final fun component3 ()I + public final fun component4 ()I + public final fun component5 ()I + public final fun component6 ()I + public final fun component7 ()I + public final fun component8 ()I + public final fun component9 ()I + public final fun copy (IIIIIIIIIII)Lcom/stripe/android/paymentsheet/PaymentSheet$Colors; + public static synthetic fun copy$default (Lcom/stripe/android/paymentsheet/PaymentSheet$Colors;IIIIIIIIIIIILjava/lang/Object;)Lcom/stripe/android/paymentsheet/PaymentSheet$Colors; + public fun describeContents ()I + public fun equals (Ljava/lang/Object;)Z + public final fun getAppBarIcon ()I + public final fun getComponentBackground ()I + public final fun getComponentBorder ()I + public final fun getComponentDivider ()I + public final fun getError ()I + public final fun getOnBackground ()I + public final fun getOnPrimary ()I + public final fun getPlaceholderText ()I + public final fun getPrimary ()I + public final fun getSurface ()I + public final fun getTextSecondary ()I + public fun hashCode ()I + public fun toString ()Ljava/lang/String; + public fun writeToParcel (Landroid/os/Parcel;I)V +} + +public final class com/stripe/android/paymentsheet/PaymentSheet$Colors$Companion { + public final fun getDefaultDark ()Lcom/stripe/android/paymentsheet/PaymentSheet$Colors; + public final fun getDefaultLight ()Lcom/stripe/android/paymentsheet/PaymentSheet$Colors; +} + public final class com/stripe/android/paymentsheet/PaymentSheet$Configuration : android/os/Parcelable { public static final field $stable I public static final field CREATOR Landroid/os/Parcelable$Creator; @@ -119,18 +193,21 @@ public final class com/stripe/android/paymentsheet/PaymentSheet$Configuration : public fun (Ljava/lang/String;Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration;Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration;Landroid/content/res/ColorStateList;)V public fun (Ljava/lang/String;Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration;Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration;Landroid/content/res/ColorStateList;Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails;)V public fun (Ljava/lang/String;Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration;Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration;Landroid/content/res/ColorStateList;Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails;Z)V - public synthetic fun (Ljava/lang/String;Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration;Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration;Landroid/content/res/ColorStateList;Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration;Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration;Landroid/content/res/ColorStateList;Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails;ZLcom/stripe/android/paymentsheet/PaymentSheet$Appearance;)V + public synthetic fun (Ljava/lang/String;Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration;Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration;Landroid/content/res/ColorStateList;Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails;ZLcom/stripe/android/paymentsheet/PaymentSheet$Appearance;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/String; public final fun component2 ()Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration; public final fun component3 ()Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration; public final fun component4 ()Landroid/content/res/ColorStateList; public final fun component5 ()Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails; public final fun component6 ()Z - public final fun copy (Ljava/lang/String;Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration;Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration;Landroid/content/res/ColorStateList;Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails;Z)Lcom/stripe/android/paymentsheet/PaymentSheet$Configuration; - public static synthetic fun copy$default (Lcom/stripe/android/paymentsheet/PaymentSheet$Configuration;Ljava/lang/String;Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration;Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration;Landroid/content/res/ColorStateList;Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails;ZILjava/lang/Object;)Lcom/stripe/android/paymentsheet/PaymentSheet$Configuration; + public final fun component7 ()Lcom/stripe/android/paymentsheet/PaymentSheet$Appearance; + public final fun copy (Ljava/lang/String;Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration;Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration;Landroid/content/res/ColorStateList;Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails;ZLcom/stripe/android/paymentsheet/PaymentSheet$Appearance;)Lcom/stripe/android/paymentsheet/PaymentSheet$Configuration; + public static synthetic fun copy$default (Lcom/stripe/android/paymentsheet/PaymentSheet$Configuration;Ljava/lang/String;Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration;Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration;Landroid/content/res/ColorStateList;Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails;ZLcom/stripe/android/paymentsheet/PaymentSheet$Appearance;ILjava/lang/Object;)Lcom/stripe/android/paymentsheet/PaymentSheet$Configuration; public fun describeContents ()I public fun equals (Ljava/lang/Object;)Z public final fun getAllowsDelayedPaymentMethods ()Z + public final fun getAppearance ()Lcom/stripe/android/paymentsheet/PaymentSheet$Appearance; public final fun getCustomer ()Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration; public final fun getDefaultBillingDetails ()Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails; public final fun getGooglePay ()Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration; @@ -145,6 +222,7 @@ public final class com/stripe/android/paymentsheet/PaymentSheet$Configuration$Bu public static final field $stable I public fun (Ljava/lang/String;)V public final fun allowsDelayedPaymentMethods (Z)Lcom/stripe/android/paymentsheet/PaymentSheet$Configuration$Builder; + public final fun appearance (Lcom/stripe/android/paymentsheet/PaymentSheet$Appearance;)Lcom/stripe/android/paymentsheet/PaymentSheet$Configuration$Builder; public final fun build ()Lcom/stripe/android/paymentsheet/PaymentSheet$Configuration; public final fun customer (Lcom/stripe/android/paymentsheet/PaymentSheet$CustomerConfiguration;)Lcom/stripe/android/paymentsheet/PaymentSheet$Configuration$Builder; public final fun defaultBillingDetails (Lcom/stripe/android/paymentsheet/PaymentSheet$BillingDetails;)Lcom/stripe/android/paymentsheet/PaymentSheet$Configuration$Builder; @@ -238,6 +316,58 @@ public final class com/stripe/android/paymentsheet/PaymentSheet$GooglePayConfigu public static fun values ()[Lcom/stripe/android/paymentsheet/PaymentSheet$GooglePayConfiguration$Environment; } +public final class com/stripe/android/paymentsheet/PaymentSheet$Shapes : android/os/Parcelable { + public static final field $stable I + public static final field CREATOR Landroid/os/Parcelable$Creator; + public static final field Companion Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes$Companion; + public fun (FFF)V + public final fun component1 ()F + public final fun component2 ()F + public final fun component3 ()F + public final fun copy (FFF)Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes; + public static synthetic fun copy$default (Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes;FFFILjava/lang/Object;)Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes; + public fun describeContents ()I + public fun equals (Ljava/lang/Object;)Z + public final fun getBorderStrokeWidthDp ()F + public final fun getBorderStrokeWidthSelected ()F + public final fun getCornerRadiusDp ()F + public fun hashCode ()I + public fun toString ()Ljava/lang/String; + public fun writeToParcel (Landroid/os/Parcel;I)V +} + +public final class com/stripe/android/paymentsheet/PaymentSheet$Shapes$Companion { + public final fun getDefault ()Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes; +} + +public final class com/stripe/android/paymentsheet/PaymentSheet$Typography : android/os/Parcelable { + public static final field $stable I + public static final field CREATOR Landroid/os/Parcelable$Creator; + public static final field Companion Lcom/stripe/android/paymentsheet/PaymentSheet$Typography$Companion; + public fun (FIIII)V + public final fun component1 ()F + public final fun component2 ()I + public final fun component3 ()I + public final fun component4 ()I + public final fun component5 ()I + public final fun copy (FIIII)Lcom/stripe/android/paymentsheet/PaymentSheet$Typography; + public static synthetic fun copy$default (Lcom/stripe/android/paymentsheet/PaymentSheet$Typography;FIIIIILjava/lang/Object;)Lcom/stripe/android/paymentsheet/PaymentSheet$Typography; + public fun describeContents ()I + public fun equals (Ljava/lang/Object;)Z + public final fun getBoldWeight ()I + public final fun getFontResId ()I + public final fun getMediumWeight ()I + public final fun getNormalWeight ()I + public final fun getSizeScaleFactor ()F + public fun hashCode ()I + public fun toString ()Ljava/lang/String; + public fun writeToParcel (Landroid/os/Parcel;I)V +} + +public final class com/stripe/android/paymentsheet/PaymentSheet$Typography$Companion { + public final fun getDefault ()Lcom/stripe/android/paymentsheet/PaymentSheet$Typography; +} + public final class com/stripe/android/paymentsheet/PaymentSheetContract : androidx/activity/result/contract/ActivityResultContract { public static final field $stable I public static final field EXTRA_ARGS Ljava/lang/String; diff --git a/payments-ui-core/res/font/roboto.ttf b/paymentsheet/res/font/roboto.ttf similarity index 100% rename from payments-ui-core/res/font/roboto.ttf rename to paymentsheet/res/font/roboto.ttf diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BasePaymentMethodsListFragment.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BasePaymentMethodsListFragment.kt index a33043f82ee..fd45a02b30e 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BasePaymentMethodsListFragment.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BasePaymentMethodsListFragment.kt @@ -13,6 +13,7 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import androidx.annotation.VisibleForTesting +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.unit.dp import androidx.core.content.res.ResourcesCompat @@ -23,7 +24,7 @@ import com.stripe.android.paymentsheet.model.FragmentConfig import com.stripe.android.paymentsheet.model.PaymentSelection import com.stripe.android.paymentsheet.ui.BaseSheetActivity import com.stripe.android.paymentsheet.viewmodels.BaseSheetViewModel -import com.stripe.android.ui.core.PaymentsThemeConfig +import com.stripe.android.ui.core.PaymentsTheme import com.stripe.android.ui.core.convertDpToPx import com.stripe.android.ui.core.isSystemDarkTheme @@ -84,37 +85,41 @@ internal abstract class BasePaymentMethodsListFragment( editMenuItem?.apply { val editMenuText = getString(if (isEditing) R.string.done else R.string.edit) val editMenuTextSpan = SpannableString(editMenuText) - editMenuTextSpan.setSpan( - ForegroundColorSpan(PaymentsThemeConfig.colors(isDark).appBarIcon.toArgb()), - 0, - editMenuTextSpan.length, - 0 - ) - val fontSize = context?.convertDpToPx( - PaymentsThemeConfig.Typography.h6.fontSize.value.dp - ) ?: 0 - editMenuTextSpan.setSpan( - AbsoluteSizeSpan(fontSize.toInt()), - 0, - editMenuTextSpan.length, - 0 - ) - context?.let { - val typeFace = ResourcesCompat.getFont( - it, - PaymentsThemeConfig.Typography.fontFamily + sheetViewModel.config?.appearance?.let { appearance -> + val color = Color(appearance.getColors(isDark).appBarIcon).toArgb() + editMenuTextSpan.setSpan( + ForegroundColorSpan(color), + 0, + editMenuTextSpan.length, + 0 ) - typeFace?.let { + + context?.let { + val typeFace = ResourcesCompat.getFont( + it, + appearance.typography.fontResId + ) + typeFace?.let { + editMenuTextSpan.setSpan( + CustomTypefaceSpan(typeFace), + 0, + editMenuTextSpan.length, + 0 + ) + } + + val fontSize = it.convertDpToPx( + (PaymentsTheme.smallFont * appearance.typography.sizeScaleFactor).dp + ) editMenuTextSpan.setSpan( - CustomTypefaceSpan(typeFace), + AbsoluteSizeSpan(fontSize.toInt()), 0, editMenuTextSpan.length, 0 ) } } - title = editMenuTextSpan } } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentOptionsActivity.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentOptionsActivity.kt index 1189bd2fda8..1e3cde0a1d9 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentOptionsActivity.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentOptionsActivity.kt @@ -9,6 +9,7 @@ import android.widget.TextView import androidx.activity.viewModels import androidx.annotation.IdRes import androidx.annotation.VisibleForTesting +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.core.os.bundleOf import androidx.core.view.doOnNextLayout @@ -23,7 +24,6 @@ import com.stripe.android.paymentsheet.databinding.ActivityPaymentOptionsBinding import com.stripe.android.paymentsheet.ui.AnimationConstants import com.stripe.android.paymentsheet.ui.BaseSheetActivity import com.stripe.android.paymentsheet.ui.PrimaryButton -import com.stripe.android.ui.core.PaymentsThemeConfig import com.stripe.android.ui.core.isSystemDarkTheme /** @@ -128,11 +128,14 @@ internal class PaymentOptionsActivity : BaseSheetActivity() viewBinding.continueButton.lockVisible = false viewBinding.continueButton.updateState(PrimaryButton.State.Ready) - viewBinding.continueButton.setDefaultBackGroundColor( - viewModel.config?.primaryButtonColor ?: ColorStateList.valueOf( - PaymentsThemeConfig.colors(baseContext.isSystemDarkTheme()).primary.toArgb() + viewModel.config?.let { + viewBinding.continueButton.setDefaultBackGroundColor( + it.primaryButtonColor ?: ColorStateList.valueOf( + Color(it.appearance.getColors(baseContext.isSystemDarkTheme()).primary).toArgb() + ) ) - ) + viewBinding.continueButton.setCornerRadius(it.appearance.shapes.cornerRadiusDp) + } addButton.setOnClickListener { viewModel.onUserSelection() diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheet.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheet.kt index 9d27e7ad17d..0043be016af 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheet.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheet.kt @@ -3,6 +3,10 @@ package com.stripe.android.paymentsheet import android.content.res.ColorStateList import android.os.Parcelable import androidx.activity.ComponentActivity +import androidx.annotation.ColorRes +import androidx.annotation.FontRes +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb import androidx.fragment.app.Fragment import com.stripe.android.model.PaymentIntent import com.stripe.android.model.SetupIntent @@ -122,7 +126,12 @@ class PaymentSheet internal constructor( * * See [payment-notification](https://stripe.com/docs/payments/payment-methods#payment-notification). */ - val allowsDelayedPaymentMethods: Boolean = false + val allowsDelayedPaymentMethods: Boolean = false, + + /** + * Describes the appearance of Payment Sheet + */ + val appearance: Appearance = Appearance() ) : Parcelable { /** * [Configuration] builder for cleaner object creation from Java. @@ -135,6 +144,7 @@ class PaymentSheet internal constructor( private var primaryButtonColor: ColorStateList? = null private var defaultBillingDetails: BillingDetails? = null private var allowsDelayedPaymentMethods: Boolean = false + private var appearance: Appearance = Appearance() fun merchantDisplayName(merchantDisplayName: String) = apply { this.merchantDisplayName = merchantDisplayName } @@ -154,13 +164,175 @@ class PaymentSheet internal constructor( fun allowsDelayedPaymentMethods(allowsDelayedPaymentMethods: Boolean) = apply { this.allowsDelayedPaymentMethods = allowsDelayedPaymentMethods } + fun appearance(appearance: Appearance) = + apply { this.appearance = appearance } + fun build() = Configuration( merchantDisplayName, customer, googlePay, primaryButtonColor, defaultBillingDetails, - allowsDelayedPaymentMethods + allowsDelayedPaymentMethods, + appearance + ) + } + } + + @Parcelize + data class Appearance( + // Describes the colors used while the system is in light mode + val colorsLight: Colors = Colors.defaultLight, + + // Describes the colors used while the system is in dark mode + val colorsDark: Colors = Colors.defaultDark, + + // Describes the appearance of shapes + val shapes: Shapes = Shapes.default, + + // Describes the typography used for text. + val typography: Typography = Typography.default, + ) : Parcelable { + fun getColors(isDark: Boolean): Colors { + return if (isDark) colorsDark else colorsLight + } + + class Builder { + private var colorsLight = Colors.defaultLight + private var colorsDark = Colors.defaultDark + private var shapes = Shapes.default + private var typography = Typography.default + + fun colorsLight(colors: Colors) = apply { this.colorsLight = colors } + fun colorsDark(colors: Colors) = apply { this.colorsDark = colors } + fun shapes(shapes: Shapes) = apply { this.shapes = shapes } + fun typography(typography: Typography) = apply { this.typography = typography } + } + } + + @Parcelize + data class Colors( + // A primary color used throughout PaymentSheet + @ColorRes + val primary: Int, + + // The color used for the surfaces (backgrounds) of PaymentSheet + @ColorRes + val surface: Int, + + // The color used for the background of inputs, tabs, and other components + @ColorRes + val componentBackground: Int, + + // The color used for borders of inputs, tabs, and other components + @ColorRes + val componentBorder: Int, + + // The color of the divider lines used inside inputs, tabs, and other components + @ColorRes + val componentDivider: Int, + + // The default color used for text and on other primary elements in Payment Sheet + @ColorRes + val onPrimary: Int, + + // The color used for text of secondary importance. For example, this color is used for the label above input fields + @ColorRes + val textSecondary: Int, + + // The color used for input placeholder text + @ColorRes + val placeholderText: Int, + + // The color used for items appearing over the background in Payment Sheet + @ColorRes + val onBackground: Int, + + // / The color used for icons in PaymentSheet, such as the close or back icons + @ColorRes + val appBarIcon: Int, + + // A color used to indicate errors or destructive actions in PaymentSheet + @ColorRes + val error: Int, + ) : Parcelable { + companion object { + val defaultLight = Colors( + primary = Color(0xFF007AFF).toArgb(), + surface = Color.White.toArgb(), + componentBackground = Color.White.toArgb(), + componentBorder = Color(0x33787880).toArgb(), + componentDivider = Color(0x33787880).toArgb(), + onPrimary = Color.Black.toArgb(), + textSecondary = Color(0x99000000).toArgb(), + placeholderText = Color(0x993C3C43).toArgb(), + onBackground = Color.Black.toArgb(), + appBarIcon = Color(0x99000000).toArgb(), + error = Color.Red.toArgb(), + ) + + val defaultDark = Colors( + primary = Color(0xFF0074D4).toArgb(), + surface = Color(0xff2e2e2e).toArgb(), + componentBackground = Color.DarkGray.toArgb(), + componentBorder = Color(0xFF787880).toArgb(), + componentDivider = Color(0xFF787880).toArgb(), + onPrimary = Color.White.toArgb(), + textSecondary = Color(0x99FFFFFF).toArgb(), + placeholderText = Color(0x61FFFFFF).toArgb(), + onBackground = Color.White.toArgb(), + appBarIcon = Color.White.toArgb(), + error = Color.Red.toArgb(), + ) + } + } + + @Parcelize + data class Shapes( + // The corner radius used for tabs, inputs, buttons, and other components in PaymentSheet + val cornerRadiusDp: Float, + + // The border used for inputs, tabs, and other components in PaymentSheet + val borderStrokeWidthDp: Float, + + // The border used for selected inputs, tabs in PaymentSheet + val borderStrokeWidthSelected: Float + ) : Parcelable { + companion object { + val default = Shapes( + cornerRadiusDp = 6.0f, + borderStrokeWidthDp = 1.0f, + borderStrokeWidthSelected = 2.0f + ) + } + } + + @Parcelize + data class Typography( + // The scale factor for all fonts in PaymentSheet, the default value is 1.0. + // When this value increases fonts will increase in size and decrease when this value is lowered + val sizeScaleFactor: Float, + + // Base weight for text + val normalWeight: Int, + + // Medium weight for text + val mediumWeight: Int, + + // Bold weight for text + val boldWeight: Int, + + // The font used in text. This should be a resource ID value. + @FontRes + val fontResId: Int, + ) : Parcelable { + companion object { + val default = Typography( + sizeScaleFactor = 1.0f, + normalWeight = 400, + mediumWeight = 500, + boldWeight = 700, + fontResId = R.font.roboto ) } } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetActivity.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetActivity.kt index cbfa9508c4a..8328f896d2b 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetActivity.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetActivity.kt @@ -10,6 +10,7 @@ import android.widget.TextView import androidx.activity.viewModels import androidx.annotation.IdRes import androidx.annotation.VisibleForTesting +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.core.os.bundleOf import androidx.core.view.doOnNextLayout @@ -27,7 +28,6 @@ import com.stripe.android.paymentsheet.model.PaymentSheetViewState import com.stripe.android.paymentsheet.ui.AnimationConstants import com.stripe.android.paymentsheet.ui.BaseSheetActivity import com.stripe.android.paymentsheet.viewmodels.BaseSheetViewModel -import com.stripe.android.ui.core.PaymentsThemeConfig import com.stripe.android.ui.core.isSystemDarkTheme import kotlinx.coroutines.launch import java.security.InvalidParameterException @@ -93,13 +93,13 @@ internal class PaymentSheetActivity : BaseSheetActivity() { try { starterArgs.config?.validate() starterArgs.clientSecret.validate() + starterArgs.config?.parseAppearance() } catch (e: InvalidParameterException) { setActivityResult(PaymentSheetResult.Failed(e)) finish() return } } - viewModel.registerFromActivity(this) viewModel.setupGooglePay( lifecycleScope, @@ -290,11 +290,21 @@ internal class PaymentSheetActivity : BaseSheetActivity() { } val isDark = baseContext.isSystemDarkTheme() - viewBinding.buyButton.setDefaultBackGroundColor( - viewModel.config?.primaryButtonColor ?: ColorStateList.valueOf( - PaymentsThemeConfig.colors(isDark).primary.toArgb() + viewModel.config?.let { + viewBinding.buyButton.setDefaultBackGroundColor( + it.primaryButtonColor ?: ColorStateList.valueOf( + Color(it.appearance.getColors(isDark).primary).toArgb() + ) ) - ) + viewBinding.buyButton.setCornerRadius(it.appearance.shapes.cornerRadiusDp) + + viewBinding.bottomSheet.setBackgroundColor( + Color(it.appearance.getColors(isDark).surface).toArgb() + ) + viewBinding.toolbar.setBackgroundColor( + Color(it.appearance.getColors(isDark).surface).toArgb() + ) + } viewBinding.buyButton.setOnClickListener { updateErrorMessage() @@ -305,13 +315,6 @@ internal class PaymentSheetActivity : BaseSheetActivity() { viewBinding.buyButton.isEnabled = isEnabled viewBinding.googlePayButton.isEnabled = isEnabled } - - viewBinding.bottomSheet.setBackgroundColor( - PaymentsThemeConfig.colors(isDark).surface.toArgb() - ) - viewBinding.toolbar.setBackgroundColor( - PaymentsThemeConfig.colors(isDark).surface.toArgb() - ) } override fun setActivityResult(result: PaymentSheetResult) { diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetConfigurationKtx.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetConfigurationKtx.kt index 2c9a60b9db9..2e21d8c0ba8 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetConfigurationKtx.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetConfigurationKtx.kt @@ -1,5 +1,20 @@ package com.stripe.android.paymentsheet +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Shapes +import androidx.compose.material.Typography +import androidx.compose.material.darkColors +import androidx.compose.material.lightColors +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.stripe.android.ui.core.PaymentsComposeColors +import com.stripe.android.ui.core.PaymentsComposeShapes +import com.stripe.android.ui.core.PaymentsTheme import java.security.InvalidParameterException internal fun PaymentSheet.Configuration.validate() { @@ -25,3 +40,118 @@ internal fun PaymentSheet.Configuration.validate() { } } } + +internal fun PaymentSheet.Configuration.parseAppearance() { + PaymentsTheme.colorsLight = PaymentsComposeColors( + colorComponentBackground = Color(appearance.colorsLight.componentBackground), + colorComponentBorder = Color(appearance.colorsLight.componentBorder), + colorComponentDivider = Color(appearance.colorsLight.componentDivider), + colorTextSecondary = Color(appearance.colorsLight.textSecondary), + colorTextCursor = Color.White, + placeholderText = Color(appearance.colorsLight.placeholderText), + + material = lightColors( + primary = Color(appearance.colorsLight.primary), + onPrimary = Color(appearance.colorsLight.onPrimary), + surface = Color(appearance.colorsLight.surface), + onBackground = Color(appearance.colorsLight.onBackground), + error = Color(appearance.colorsLight.error), + ) + ) + + PaymentsTheme.colorsDark = PaymentsComposeColors( + colorComponentBackground = Color(appearance.colorsDark.componentBackground), + colorComponentBorder = Color(appearance.colorsDark.componentBorder), + colorComponentDivider = Color(appearance.colorsDark.componentDivider), + colorTextSecondary = Color(appearance.colorsDark.textSecondary), + colorTextCursor = Color.Black, + placeholderText = Color(appearance.colorsDark.placeholderText), + + material = darkColors( + primary = Color(appearance.colorsDark.primary), + onPrimary = Color(appearance.colorsDark.onPrimary), + surface = Color(appearance.colorsDark.surface), + onBackground = Color(appearance.colorsDark.onBackground), + error = Color(appearance.colorsDark.error), + ) + ) + + PaymentsTheme.shapes = PaymentsComposeShapes( + borderStrokeWidth = appearance.shapes.borderStrokeWidthDp.dp, + borderStrokeWidthSelected = appearance.shapes.borderStrokeWidthSelected.dp, + material = Shapes( + small = RoundedCornerShape(appearance.shapes.cornerRadiusDp.dp), + medium = RoundedCornerShape(appearance.shapes.cornerRadiusDp.dp) + ) + ) + + // h4 is our largest headline. It is used for the most important labels in our UI + // ex: "Select your payment method" in Payment Sheet. + val h4 = TextStyle.Default.copy( + fontFamily = FontFamily(Font(appearance.typography.fontResId)), + fontSize = (PaymentsTheme.extraLargeFont * appearance.typography.sizeScaleFactor).sp, + fontWeight = FontWeight(appearance.typography.boldWeight), + ) + + // h5 is our medium headline label. + // ex: "Pay $50.99" in Payment Sheet's buy button. + val h5 = TextStyle.Default.copy( + fontFamily = FontFamily(Font(appearance.typography.fontResId)), + fontSize = (PaymentsTheme.largeFont * appearance.typography.sizeScaleFactor).sp, + fontWeight = FontWeight(appearance.typography.mediumWeight), + letterSpacing = (-0.32).sp + ) + + // h6 is our smallest headline label. + // ex: Section labels in Payment Sheet + val h6 = TextStyle.Default.copy( + fontFamily = FontFamily(Font(appearance.typography.fontResId)), + fontSize = (PaymentsTheme.smallFont * appearance.typography.sizeScaleFactor).sp, + fontWeight = FontWeight(appearance.typography.mediumWeight), + letterSpacing = (-0.15).sp + ) + + // body1 is our larger body text. Used for the bulk of our elements and forms. + // ex: the text used in Payment Sheet's text form elements. + val body1 = TextStyle.Default.copy( + fontFamily = FontFamily(Font(appearance.typography.fontResId)), + fontSize = (PaymentsTheme.mediumFont * appearance.typography.sizeScaleFactor).sp, + fontWeight = FontWeight(appearance.typography.normalWeight), + ) + + // subtitle1 is our only subtitle size. Used for labeling fields. + // ex: the placeholder texts that appear when you type in Payment Sheet's forms. + val subtitle1 = TextStyle.Default.copy( + fontFamily = FontFamily(Font(appearance.typography.fontResId)), + fontSize = (PaymentsTheme.mediumFont * appearance.typography.sizeScaleFactor).sp, + fontWeight = FontWeight(appearance.typography.normalWeight), + letterSpacing = (-0.15).sp + ) + + // caption is used to label images in payment sheet. + // ex: the labels under our payment method selectors in Payment Sheet. + val caption = TextStyle.Default.copy( + fontFamily = FontFamily(Font(appearance.typography.fontResId)), + fontSize = (PaymentsTheme.xsmallFont * appearance.typography.sizeScaleFactor).sp, + fontWeight = FontWeight(appearance.typography.mediumWeight) + ) + + // body2 is our smaller body text. Used for less important fields that are not required to + // read. Ex: our mandate texts in Payment Sheet. + val body2 = TextStyle.Default.copy( + fontFamily = FontFamily(Font(appearance.typography.fontResId)), + fontSize = (PaymentsTheme.xxsmallFont * appearance.typography.sizeScaleFactor).sp, + fontWeight = FontWeight(appearance.typography.normalWeight), + letterSpacing = (-0.15).sp + ) + + PaymentsTheme.typography = Typography( + body1 = body1, + body2 = body2, + h4 = h4, + h5 = h5, + h6 = h6, + subtitle1 = subtitle1, + caption = caption + ) +} diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/BaseSheetActivity.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/BaseSheetActivity.kt index 97a58ad71c2..290bcbf36d9 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/BaseSheetActivity.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/BaseSheetActivity.kt @@ -18,6 +18,7 @@ import androidx.annotation.StringRes import androidx.annotation.VisibleForTesting import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.content.res.AppCompatResources +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.MaterialToolbar @@ -25,7 +26,6 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior import com.stripe.android.paymentsheet.BottomSheetController import com.stripe.android.paymentsheet.R import com.stripe.android.paymentsheet.viewmodels.BaseSheetViewModel -import com.stripe.android.ui.core.PaymentsThemeConfig import com.stripe.android.ui.core.isSystemDarkTheme import com.stripe.android.view.KeyboardController import kotlin.math.roundToInt @@ -153,14 +153,17 @@ internal abstract class BaseSheetActivity : AppCompatActivity() { ) } - val navigationIconDrawable = AppCompatResources.getDrawable(this, toolbarResources.icon) - navigationIconDrawable?.setTintList( - ColorStateList.valueOf( - PaymentsThemeConfig.colors(baseContext.isSystemDarkTheme()).appBarIcon.toArgb() + viewModel.config?.appearance?.let { + val navigationIconDrawable = AppCompatResources.getDrawable(this, toolbarResources.icon) + navigationIconDrawable?.setTintList( + ColorStateList.valueOf( + Color(it.getColors(baseContext.isSystemDarkTheme()).appBarIcon).toArgb() + ) ) - ) - toolbar.navigationIcon = navigationIconDrawable + toolbar.navigationIcon = navigationIconDrawable + } + toolbar.navigationContentDescription = resources.getString(toolbarResources.description) } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/PrimaryButton.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/PrimaryButton.kt index d09eb251cb7..31dd6f421ff 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/PrimaryButton.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/PrimaryButton.kt @@ -18,10 +18,10 @@ import androidx.compose.ui.unit.dp import androidx.core.content.withStyledAttributes import androidx.core.view.isVisible import androidx.core.view.setPadding +import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.R import com.stripe.android.paymentsheet.databinding.PrimaryButtonBinding import com.stripe.android.ui.core.PaymentsTheme -import com.stripe.android.ui.core.PaymentsThemeConfig import com.stripe.android.ui.core.convertDpToPx /** @@ -53,6 +53,8 @@ internal class PrimaryButton @JvmOverloads constructor( private val confirmedIcon = viewBinding.confirmedIcon + private var cornerRadius = context.convertDpToPx(PaymentSheet.Shapes.default.cornerRadiusDp.dp) + init { viewBinding.label.setViewCompositionStrategy( ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed @@ -70,9 +72,11 @@ internal class PrimaryButton @JvmOverloads constructor( defaultTintList = tintList } - override fun setBackgroundTintList(tintList: ColorStateList?) { - val cornerRadius = context.convertDpToPx(PaymentsThemeConfig.Shapes.cornerRadius) + fun setCornerRadius(radius: Float) { + cornerRadius = context.convertDpToPx(radius.dp) + } + override fun setBackgroundTintList(tintList: ColorStateList?) { val shape = GradientDrawable() shape.shape = GradientDrawable.RECTANGLE shape.cornerRadius = cornerRadius diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/GooglePayButtonTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/GooglePayButtonTest.kt index 05a0c0545e8..69673488909 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/GooglePayButtonTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/GooglePayButtonTest.kt @@ -36,6 +36,7 @@ class GooglePayButtonTest { context, ApiKeyFixtures.FAKE_PUBLISHABLE_KEY ) + PaymentSheetFixtures.CONFIG_MINIMUM.parseAppearance() } @Test diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsActivityTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsActivityTest.kt index 139628bde44..2b324518714 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsActivityTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsActivityTest.kt @@ -56,6 +56,7 @@ class PaymentOptionsActivityTest { ApplicationProvider.getApplicationContext(), ApiKeyFixtures.FAKE_PUBLISHABLE_KEY ) + PaymentSheetFixtures.CONFIG_MINIMUM.parseAppearance() } @Test diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsAddPaymentMethodFragmentTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsAddPaymentMethodFragmentTest.kt index 176f6967cb9..15cbdf41765 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsAddPaymentMethodFragmentTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsAddPaymentMethodFragmentTest.kt @@ -35,6 +35,7 @@ internal class PaymentOptionsAddPaymentMethodFragmentTest : PaymentOptionsViewMo ApplicationProvider.getApplicationContext(), ApiKeyFixtures.FAKE_PUBLISHABLE_KEY ) + PaymentSheetFixtures.CONFIG_MINIMUM.parseAppearance() } @After From bde4cb0629518926c263dfbf79173494507c95cd Mon Sep 17 00:00:00 2001 From: Skyler Reimer Date: Thu, 24 Mar 2022 18:56:11 -0700 Subject: [PATCH 2/5] attempt #2 --- .../res/font/roboto.ttf | Bin .../stripe/android/ui/core/PaymentsTheme.kt | 244 +++++++++++++++++- paymentsheet/api/paymentsheet.api | 8 +- .../BasePaymentMethodsListFragment.kt | 7 +- .../android/paymentsheet/PaymentSheet.kt | 65 +++-- .../paymentsheet/PaymentSheetActivity.kt | 2 +- .../PaymentSheetConfigurationKtx.kt | 150 +++-------- .../android/paymentsheet/ui/PrimaryButton.kt | 4 +- .../paymentsheet/GooglePayButtonTest.kt | 1 - .../PaymentOptionsActivityTest.kt | 1 - ...mentOptionsAddPaymentMethodFragmentTest.kt | 1 - 11 files changed, 302 insertions(+), 181 deletions(-) rename {paymentsheet => payments-ui-core}/res/font/roboto.ttf (100%) diff --git a/paymentsheet/res/font/roboto.ttf b/payments-ui-core/res/font/roboto.ttf similarity index 100% rename from paymentsheet/res/font/roboto.ttf rename to payments-ui-core/res/font/roboto.ttf diff --git a/payments-ui-core/src/main/java/com/stripe/android/ui/core/PaymentsTheme.kt b/payments-ui-core/src/main/java/com/stripe/android/ui/core/PaymentsTheme.kt index 11560275479..ece4fd0feb9 100644 --- a/payments-ui-core/src/main/java/com/stripe/android/ui/core/PaymentsTheme.kt +++ b/payments-ui-core/src/main/java/com/stripe/android/ui/core/PaymentsTheme.kt @@ -3,19 +3,124 @@ package com.stripe.android.ui.core import android.content.Context import android.content.res.Configuration.UI_MODE_NIGHT_MASK import android.content.res.Configuration.UI_MODE_NIGHT_YES +import androidx.annotation.FontRes import androidx.annotation.RestrictTo import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Colors import androidx.compose.material.MaterialTheme import androidx.compose.material.Shapes import androidx.compose.material.Typography +import androidx.compose.material.lightColors import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +data class PaymentsColors( + val primary: Color, + val surface: Color, + val componentBackground: Color, + val componentBorder: Color, + val componentDivider: Color, + val onPrimary: Color, + val textSecondary: Color, + val textCursor: Color, + val placeholderText: Color, + val onBackground: Color, + val appBarIcon: Color, + val error: Color, +) + +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +data class PaymentsShapes( + val cornerRadius: Float, + val borderStrokeWidth: Float, + val borderStrokeWidthSelected: Float, +) + +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +data class PaymentsTypography( + val fontWeightNormal: Int, + val fontWeightMedium: Int, + val fontWeightBold: Int, + val fontSizeMultiplier: Float, + val xxSmallFont: Float, + val xSmallFont: Float, + val smallFont: Float, + val mediumFont: Float, + val largeFont: Float, + val xLargeFont: Float, + @FontRes + val fontFamily: Int +) + +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +object PaymentsThemeDefaults { + fun colors(isDark: Boolean): PaymentsColors { + return if (isDark) colorsDark else colorsLight + } + + val colorsLight = PaymentsColors( + primary = Color(0xFF007AFF), + surface = Color.White, + componentBackground = Color.White, + componentBorder = Color(0x33787880), + componentDivider = Color(0x33787880), + onPrimary = Color.Black, + textSecondary = Color(0x99000000), + textCursor = Color.Black, + placeholderText = Color(0x993C3C43), + onBackground = Color.Black, + appBarIcon = Color(0x99000000), + error = Color.Red, + ) + + val colorsDark = PaymentsColors( + primary = Color(0xFF0074D4), + surface = Color(0xff2e2e2e), + componentBackground = Color.DarkGray, + componentBorder = Color(0xFF787880), + componentDivider = Color(0xFF787880), + onPrimary = Color.White, + textSecondary = Color(0x99FFFFFF), + textCursor = Color.White, + placeholderText = Color(0x61FFFFFF), + onBackground = Color.White, + appBarIcon = Color.White, + error = Color.Red, + ) + + val shapes = PaymentsShapes( + cornerRadius = 6.0f, + borderStrokeWidth = 1.0f, + borderStrokeWidthSelected = 2.0f + ) + + val typography = PaymentsTypography( + fontWeightNormal = FontWeight.Normal.weight, + fontWeightMedium = FontWeight.Medium.weight, + fontWeightBold = FontWeight.Bold.weight, + fontSizeMultiplier = 1.0F, + xxSmallFont = 9.0F, + xSmallFont = 12.0F, + smallFont = 13.0F, + mediumFont = 14.0F, + largeFont = 16.0F, + xLargeFont = 20.0F, + fontFamily = R.font.roboto + ) +} @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) data class PaymentsComposeColors( @@ -35,6 +140,117 @@ data class PaymentsComposeShapes( val material: Shapes ) +@Composable +@ReadOnlyComposable +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +fun PaymentsColors.toComposeColors(): PaymentsComposeColors { + return PaymentsComposeColors( + colorComponentBackground = componentBackground, + colorComponentBorder = componentBorder, + colorComponentDivider = componentDivider, + colorTextSecondary = textSecondary, + colorTextCursor = textCursor, + placeholderText = placeholderText, + + material = lightColors( + primary = primary, + onPrimary = onPrimary, + surface = surface, + onBackground = onBackground, + error = error, + ) + ) +} + +@Composable +@ReadOnlyComposable +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +fun PaymentsShapes.toComposeShapes(): PaymentsComposeShapes { + return PaymentsComposeShapes( + borderStrokeWidth = borderStrokeWidth.dp, + borderStrokeWidthSelected = borderStrokeWidthSelected.dp, + material = MaterialTheme.shapes.copy( + small = RoundedCornerShape(cornerRadius.dp), + medium = RoundedCornerShape(cornerRadius.dp) + ) + ) +} + +@Composable +@ReadOnlyComposable +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +fun PaymentsTypography.toComposeTypography(): Typography { + // h4 is our largest headline. It is used for the most important labels in our UI + // ex: "Select your payment method" in Payment Sheet. + val h4 = TextStyle.Default.copy( + fontFamily = FontFamily(Font(fontFamily)), + fontSize = (xLargeFont * fontSizeMultiplier).sp, + fontWeight = FontWeight(fontWeightBold), + ) + + // h5 is our medium headline label. + // ex: "Pay $50.99" in Payment Sheet's buy button. + val h5 = TextStyle.Default.copy( + fontFamily = FontFamily(Font(fontFamily)), + fontSize = (largeFont * fontSizeMultiplier).sp, + fontWeight = FontWeight(fontWeightMedium), + letterSpacing = (-0.32).sp + ) + + // h6 is our smallest headline label. + // ex: Section labels in Payment Sheet + val h6 = TextStyle.Default.copy( + fontFamily = FontFamily(Font(fontFamily)), + fontSize = (smallFont * fontSizeMultiplier).sp, + fontWeight = FontWeight(fontWeightMedium), + letterSpacing = (-0.15).sp + ) + + // body1 is our larger body text. Used for the bulk of our elements and forms. + // ex: the text used in Payment Sheet's text form elements. + val body1 = TextStyle.Default.copy( + fontFamily = FontFamily(Font(fontFamily)), + fontSize = (mediumFont * fontSizeMultiplier).sp, + fontWeight = FontWeight(fontWeightNormal), + ) + + // subtitle1 is our only subtitle size. Used for labeling fields. + // ex: the placeholder texts that appear when you type in Payment Sheet's forms. + val subtitle1 = TextStyle.Default.copy( + fontFamily = FontFamily(Font(fontFamily)), + fontSize = (mediumFont * fontSizeMultiplier).sp, + fontWeight = FontWeight(fontWeightNormal), + letterSpacing = (-0.15).sp + ) + + // caption is used to label images in payment sheet. + // ex: the labels under our payment method selectors in Payment Sheet. + val caption = TextStyle.Default.copy( + fontFamily = FontFamily(Font(fontFamily)), + fontSize = (xSmallFont * fontSizeMultiplier).sp, + fontWeight = FontWeight(fontWeightMedium) + ) + + // body2 is our smaller body text. Used for less important fields that are not required to + // read. Ex: our mandate texts in Payment Sheet. + val body2 = TextStyle.Default.copy( + fontFamily = FontFamily(Font(fontFamily)), + fontSize = (xxSmallFont * fontSizeMultiplier).sp, + fontWeight = FontWeight(fontWeightNormal), + letterSpacing = (-0.15).sp + ) + + return MaterialTheme.typography.copy( + body1 = body1, + body2 = body2, + h4 = h4, + h5 = h5, + h6 = h6, + subtitle1 = subtitle1, + caption = caption + ) +} + @Composable @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) fun PaymentsTheme( @@ -51,9 +267,9 @@ fun PaymentsTheme( localShapes provides shapes ) { MaterialTheme( - colors = PaymentsTheme.colors.material, + colors = colors.material, typography = PaymentsTheme.typography, - shapes = PaymentsTheme.shapes.material, + shapes = shapes.material, content = content ) } @@ -64,22 +280,24 @@ fun PaymentsTheme( // This mirrors an object that lives inside of MaterialTheme. @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) object PaymentsTheme { - lateinit var colorsLight: PaymentsComposeColors - lateinit var colorsDark: PaymentsComposeColors + var colorsDarkMutable = PaymentsThemeDefaults.colorsDark + var colorsLightMutable = PaymentsThemeDefaults.colorsLight val colors: PaymentsComposeColors @Composable @ReadOnlyComposable - get() = if (isSystemInDarkTheme()) colorsDark else colorsLight + get() = (if (isSystemInDarkTheme()) colorsDarkMutable else colorsLightMutable).toComposeColors() - lateinit var shapes: PaymentsComposeShapes + var shapesMutable = PaymentsThemeDefaults.shapes + val shapes: PaymentsComposeShapes + @Composable + @ReadOnlyComposable + get() = shapesMutable.toComposeShapes() - lateinit var typography: Typography - const val xxsmallFont = 9.0 - const val xsmallFont = 12.0 - const val smallFont = 13.0 - const val mediumFont = 14.0 - const val largeFont = 16.0 - const val extraLargeFont = 20.0 + var typographyMutable = PaymentsThemeDefaults.typography + val typography: Typography + @Composable + @ReadOnlyComposable + get() = typographyMutable.toComposeTypography() @Composable @ReadOnlyComposable diff --git a/paymentsheet/api/paymentsheet.api b/paymentsheet/api/paymentsheet.api index 0f107d9a5a2..815d70d273c 100644 --- a/paymentsheet/api/paymentsheet.api +++ b/paymentsheet/api/paymentsheet.api @@ -320,16 +320,14 @@ public final class com/stripe/android/paymentsheet/PaymentSheet$Shapes : android public static final field $stable I public static final field CREATOR Landroid/os/Parcelable$Creator; public static final field Companion Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes$Companion; - public fun (FFF)V + public fun (FF)V public final fun component1 ()F public final fun component2 ()F - public final fun component3 ()F - public final fun copy (FFF)Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes; - public static synthetic fun copy$default (Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes;FFFILjava/lang/Object;)Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes; + public final fun copy (FF)Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes; + public static synthetic fun copy$default (Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes;FFILjava/lang/Object;)Lcom/stripe/android/paymentsheet/PaymentSheet$Shapes; public fun describeContents ()I public fun equals (Ljava/lang/Object;)Z public final fun getBorderStrokeWidthDp ()F - public final fun getBorderStrokeWidthSelected ()F public final fun getCornerRadiusDp ()F public fun hashCode ()I public fun toString ()Ljava/lang/String; diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BasePaymentMethodsListFragment.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BasePaymentMethodsListFragment.kt index fd45a02b30e..2b2e15e1974 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BasePaymentMethodsListFragment.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BasePaymentMethodsListFragment.kt @@ -24,7 +24,7 @@ import com.stripe.android.paymentsheet.model.FragmentConfig import com.stripe.android.paymentsheet.model.PaymentSelection import com.stripe.android.paymentsheet.ui.BaseSheetActivity import com.stripe.android.paymentsheet.viewmodels.BaseSheetViewModel -import com.stripe.android.ui.core.PaymentsTheme +import com.stripe.android.ui.core.PaymentsThemeDefaults import com.stripe.android.ui.core.convertDpToPx import com.stripe.android.ui.core.isSystemDarkTheme @@ -110,7 +110,10 @@ internal abstract class BasePaymentMethodsListFragment( } val fontSize = it.convertDpToPx( - (PaymentsTheme.smallFont * appearance.typography.sizeScaleFactor).dp + ( + PaymentsThemeDefaults.typography.smallFont + * appearance.typography.sizeScaleFactor + ).dp ) editMenuTextSpan.setSpan( AbsoluteSizeSpan(fontSize.toInt()), diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheet.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheet.kt index 0043be016af..f49b62a124e 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheet.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheet.kt @@ -5,13 +5,13 @@ import android.os.Parcelable import androidx.activity.ComponentActivity import androidx.annotation.ColorRes import androidx.annotation.FontRes -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.fragment.app.Fragment import com.stripe.android.model.PaymentIntent import com.stripe.android.model.SetupIntent import com.stripe.android.paymentsheet.flowcontroller.FlowControllerFactory import com.stripe.android.paymentsheet.model.PaymentOption +import com.stripe.android.ui.core.PaymentsThemeDefaults import kotlinx.parcelize.Parcelize /** @@ -258,31 +258,32 @@ class PaymentSheet internal constructor( ) : Parcelable { companion object { val defaultLight = Colors( - primary = Color(0xFF007AFF).toArgb(), - surface = Color.White.toArgb(), - componentBackground = Color.White.toArgb(), - componentBorder = Color(0x33787880).toArgb(), - componentDivider = Color(0x33787880).toArgb(), - onPrimary = Color.Black.toArgb(), - textSecondary = Color(0x99000000).toArgb(), - placeholderText = Color(0x993C3C43).toArgb(), - onBackground = Color.Black.toArgb(), - appBarIcon = Color(0x99000000).toArgb(), - error = Color.Red.toArgb(), + primary = PaymentsThemeDefaults.colorsLight.primary.toArgb(), + surface = PaymentsThemeDefaults.colorsLight.surface.toArgb(), + componentBackground = PaymentsThemeDefaults + .colorsLight.componentBackground.toArgb(), + componentBorder = PaymentsThemeDefaults.colorsLight.componentBorder.toArgb(), + componentDivider = PaymentsThemeDefaults.colorsLight.componentDivider.toArgb(), + onPrimary = PaymentsThemeDefaults.colorsLight.onPrimary.toArgb(), + textSecondary = PaymentsThemeDefaults.colorsLight.textSecondary.toArgb(), + placeholderText = PaymentsThemeDefaults.colorsLight.placeholderText.toArgb(), + onBackground = PaymentsThemeDefaults.colorsLight.onBackground.toArgb(), + appBarIcon = PaymentsThemeDefaults.colorsLight.appBarIcon.toArgb(), + error = PaymentsThemeDefaults.colorsLight.error.toArgb(), ) val defaultDark = Colors( - primary = Color(0xFF0074D4).toArgb(), - surface = Color(0xff2e2e2e).toArgb(), - componentBackground = Color.DarkGray.toArgb(), - componentBorder = Color(0xFF787880).toArgb(), - componentDivider = Color(0xFF787880).toArgb(), - onPrimary = Color.White.toArgb(), - textSecondary = Color(0x99FFFFFF).toArgb(), - placeholderText = Color(0x61FFFFFF).toArgb(), - onBackground = Color.White.toArgb(), - appBarIcon = Color.White.toArgb(), - error = Color.Red.toArgb(), + primary = PaymentsThemeDefaults.colorsDark.primary.toArgb(), + surface = PaymentsThemeDefaults.colorsDark.surface.toArgb(), + componentBackground = PaymentsThemeDefaults.colorsDark.componentBackground.toArgb(), + componentBorder = PaymentsThemeDefaults.colorsDark.componentBorder.toArgb(), + componentDivider = PaymentsThemeDefaults.colorsDark.componentDivider.toArgb(), + onPrimary = PaymentsThemeDefaults.colorsDark.onPrimary.toArgb(), + textSecondary = PaymentsThemeDefaults.colorsDark.textSecondary.toArgb(), + placeholderText = PaymentsThemeDefaults.colorsDark.placeholderText.toArgb(), + onBackground = PaymentsThemeDefaults.colorsDark.onBackground.toArgb(), + appBarIcon = PaymentsThemeDefaults.colorsDark.appBarIcon.toArgb(), + error = PaymentsThemeDefaults.colorsDark.error.toArgb(), ) } } @@ -294,15 +295,11 @@ class PaymentSheet internal constructor( // The border used for inputs, tabs, and other components in PaymentSheet val borderStrokeWidthDp: Float, - - // The border used for selected inputs, tabs in PaymentSheet - val borderStrokeWidthSelected: Float ) : Parcelable { companion object { val default = Shapes( - cornerRadiusDp = 6.0f, - borderStrokeWidthDp = 1.0f, - borderStrokeWidthSelected = 2.0f + cornerRadiusDp = PaymentsThemeDefaults.shapes.cornerRadius, + borderStrokeWidthDp = PaymentsThemeDefaults.shapes.borderStrokeWidth, ) } } @@ -328,11 +325,11 @@ class PaymentSheet internal constructor( ) : Parcelable { companion object { val default = Typography( - sizeScaleFactor = 1.0f, - normalWeight = 400, - mediumWeight = 500, - boldWeight = 700, - fontResId = R.font.roboto + sizeScaleFactor = PaymentsThemeDefaults.typography.fontSizeMultiplier, + normalWeight = PaymentsThemeDefaults.typography.fontWeightNormal, + mediumWeight = PaymentsThemeDefaults.typography.fontWeightMedium, + boldWeight = PaymentsThemeDefaults.typography.fontWeightBold, + fontResId = PaymentsThemeDefaults.typography.fontFamily ) } } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetActivity.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetActivity.kt index 8328f896d2b..894b63e3ac7 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetActivity.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetActivity.kt @@ -93,7 +93,7 @@ internal class PaymentSheetActivity : BaseSheetActivity() { try { starterArgs.config?.validate() starterArgs.clientSecret.validate() - starterArgs.config?.parseAppearance() + starterArgs.config?.appearance?.parseAppearance() } catch (e: InvalidParameterException) { setActivityResult(PaymentSheetResult.Failed(e)) finish() diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetConfigurationKtx.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetConfigurationKtx.kt index 2e21d8c0ba8..ac02b49613c 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetConfigurationKtx.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetConfigurationKtx.kt @@ -1,20 +1,8 @@ package com.stripe.android.paymentsheet -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Shapes -import androidx.compose.material.Typography -import androidx.compose.material.darkColors -import androidx.compose.material.lightColors import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.Font -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.stripe.android.ui.core.PaymentsComposeColors -import com.stripe.android.ui.core.PaymentsComposeShapes import com.stripe.android.ui.core.PaymentsTheme +import com.stripe.android.ui.core.PaymentsThemeDefaults import java.security.InvalidParameterException internal fun PaymentSheet.Configuration.validate() { @@ -41,117 +29,37 @@ internal fun PaymentSheet.Configuration.validate() { } } -internal fun PaymentSheet.Configuration.parseAppearance() { - PaymentsTheme.colorsLight = PaymentsComposeColors( - colorComponentBackground = Color(appearance.colorsLight.componentBackground), - colorComponentBorder = Color(appearance.colorsLight.componentBorder), - colorComponentDivider = Color(appearance.colorsLight.componentDivider), - colorTextSecondary = Color(appearance.colorsLight.textSecondary), - colorTextCursor = Color.White, - placeholderText = Color(appearance.colorsLight.placeholderText), - - material = lightColors( - primary = Color(appearance.colorsLight.primary), - onPrimary = Color(appearance.colorsLight.onPrimary), - surface = Color(appearance.colorsLight.surface), - onBackground = Color(appearance.colorsLight.onBackground), - error = Color(appearance.colorsLight.error), - ) - ) - - PaymentsTheme.colorsDark = PaymentsComposeColors( - colorComponentBackground = Color(appearance.colorsDark.componentBackground), - colorComponentBorder = Color(appearance.colorsDark.componentBorder), - colorComponentDivider = Color(appearance.colorsDark.componentDivider), - colorTextSecondary = Color(appearance.colorsDark.textSecondary), - colorTextCursor = Color.Black, - placeholderText = Color(appearance.colorsDark.placeholderText), - - material = darkColors( - primary = Color(appearance.colorsDark.primary), - onPrimary = Color(appearance.colorsDark.onPrimary), - surface = Color(appearance.colorsDark.surface), - onBackground = Color(appearance.colorsDark.onBackground), - error = Color(appearance.colorsDark.error), - ) - ) - - PaymentsTheme.shapes = PaymentsComposeShapes( - borderStrokeWidth = appearance.shapes.borderStrokeWidthDp.dp, - borderStrokeWidthSelected = appearance.shapes.borderStrokeWidthSelected.dp, - material = Shapes( - small = RoundedCornerShape(appearance.shapes.cornerRadiusDp.dp), - medium = RoundedCornerShape(appearance.shapes.cornerRadiusDp.dp) - ) - ) - - // h4 is our largest headline. It is used for the most important labels in our UI - // ex: "Select your payment method" in Payment Sheet. - val h4 = TextStyle.Default.copy( - fontFamily = FontFamily(Font(appearance.typography.fontResId)), - fontSize = (PaymentsTheme.extraLargeFont * appearance.typography.sizeScaleFactor).sp, - fontWeight = FontWeight(appearance.typography.boldWeight), - ) - - // h5 is our medium headline label. - // ex: "Pay $50.99" in Payment Sheet's buy button. - val h5 = TextStyle.Default.copy( - fontFamily = FontFamily(Font(appearance.typography.fontResId)), - fontSize = (PaymentsTheme.largeFont * appearance.typography.sizeScaleFactor).sp, - fontWeight = FontWeight(appearance.typography.mediumWeight), - letterSpacing = (-0.32).sp - ) - - // h6 is our smallest headline label. - // ex: Section labels in Payment Sheet - val h6 = TextStyle.Default.copy( - fontFamily = FontFamily(Font(appearance.typography.fontResId)), - fontSize = (PaymentsTheme.smallFont * appearance.typography.sizeScaleFactor).sp, - fontWeight = FontWeight(appearance.typography.mediumWeight), - letterSpacing = (-0.15).sp - ) - - // body1 is our larger body text. Used for the bulk of our elements and forms. - // ex: the text used in Payment Sheet's text form elements. - val body1 = TextStyle.Default.copy( - fontFamily = FontFamily(Font(appearance.typography.fontResId)), - fontSize = (PaymentsTheme.mediumFont * appearance.typography.sizeScaleFactor).sp, - fontWeight = FontWeight(appearance.typography.normalWeight), - ) - - // subtitle1 is our only subtitle size. Used for labeling fields. - // ex: the placeholder texts that appear when you type in Payment Sheet's forms. - val subtitle1 = TextStyle.Default.copy( - fontFamily = FontFamily(Font(appearance.typography.fontResId)), - fontSize = (PaymentsTheme.mediumFont * appearance.typography.sizeScaleFactor).sp, - fontWeight = FontWeight(appearance.typography.normalWeight), - letterSpacing = (-0.15).sp - ) - - // caption is used to label images in payment sheet. - // ex: the labels under our payment method selectors in Payment Sheet. - val caption = TextStyle.Default.copy( - fontFamily = FontFamily(Font(appearance.typography.fontResId)), - fontSize = (PaymentsTheme.xsmallFont * appearance.typography.sizeScaleFactor).sp, - fontWeight = FontWeight(appearance.typography.mediumWeight) +internal fun PaymentSheet.Appearance.parseAppearance() { + PaymentsTheme.colorsLightMutable = PaymentsThemeDefaults.colorsLight.copy( + primary = Color(colorsLight.primary), + surface = Color(colorsLight.surface), + componentBackground = Color(colorsLight.componentBackground), + componentBorder = Color(colorsLight.componentBorder), + componentDivider = Color(colorsLight.componentDivider), + onPrimary = Color(colorsLight.onPrimary), + textSecondary = Color(colorsLight.textSecondary), + placeholderText = Color(colorsLight.placeholderText), + onBackground = Color(colorsLight.onBackground), + appBarIcon = Color(colorsLight.appBarIcon), + error = Color(colorsLight.error) ) - // body2 is our smaller body text. Used for less important fields that are not required to - // read. Ex: our mandate texts in Payment Sheet. - val body2 = TextStyle.Default.copy( - fontFamily = FontFamily(Font(appearance.typography.fontResId)), - fontSize = (PaymentsTheme.xxsmallFont * appearance.typography.sizeScaleFactor).sp, - fontWeight = FontWeight(appearance.typography.normalWeight), - letterSpacing = (-0.15).sp + PaymentsTheme.colorsDarkMutable = PaymentsThemeDefaults.colorsDark.copy( + primary = Color(colorsDark.primary), + surface = Color(colorsDark.surface), + componentBackground = Color(colorsDark.componentBackground), + componentBorder = Color(colorsDark.componentBorder), + componentDivider = Color(colorsDark.componentDivider), + onPrimary = Color(colorsDark.onPrimary), + textSecondary = Color(colorsDark.textSecondary), + placeholderText = Color(colorsDark.placeholderText), + onBackground = Color(colorsDark.onBackground), + appBarIcon = Color(colorsDark.appBarIcon), + error = Color(colorsDark.error) ) - PaymentsTheme.typography = Typography( - body1 = body1, - body2 = body2, - h4 = h4, - h5 = h5, - h6 = h6, - subtitle1 = subtitle1, - caption = caption + PaymentsTheme.shapesMutable = PaymentsThemeDefaults.shapes.copy( + cornerRadius = shapes.cornerRadiusDp, + borderStrokeWidth = shapes.borderStrokeWidthDp ) } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/PrimaryButton.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/PrimaryButton.kt index 31dd6f421ff..e9bd71811d3 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/PrimaryButton.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/PrimaryButton.kt @@ -18,10 +18,10 @@ import androidx.compose.ui.unit.dp import androidx.core.content.withStyledAttributes import androidx.core.view.isVisible import androidx.core.view.setPadding -import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.R import com.stripe.android.paymentsheet.databinding.PrimaryButtonBinding import com.stripe.android.ui.core.PaymentsTheme +import com.stripe.android.ui.core.PaymentsThemeDefaults import com.stripe.android.ui.core.convertDpToPx /** @@ -53,7 +53,7 @@ internal class PrimaryButton @JvmOverloads constructor( private val confirmedIcon = viewBinding.confirmedIcon - private var cornerRadius = context.convertDpToPx(PaymentSheet.Shapes.default.cornerRadiusDp.dp) + private var cornerRadius = context.convertDpToPx(PaymentsThemeDefaults.shapes.cornerRadius.dp) init { viewBinding.label.setViewCompositionStrategy( diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/GooglePayButtonTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/GooglePayButtonTest.kt index 69673488909..05a0c0545e8 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/GooglePayButtonTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/GooglePayButtonTest.kt @@ -36,7 +36,6 @@ class GooglePayButtonTest { context, ApiKeyFixtures.FAKE_PUBLISHABLE_KEY ) - PaymentSheetFixtures.CONFIG_MINIMUM.parseAppearance() } @Test diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsActivityTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsActivityTest.kt index 2b324518714..139628bde44 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsActivityTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsActivityTest.kt @@ -56,7 +56,6 @@ class PaymentOptionsActivityTest { ApplicationProvider.getApplicationContext(), ApiKeyFixtures.FAKE_PUBLISHABLE_KEY ) - PaymentSheetFixtures.CONFIG_MINIMUM.parseAppearance() } @Test diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsAddPaymentMethodFragmentTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsAddPaymentMethodFragmentTest.kt index 15cbdf41765..176f6967cb9 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsAddPaymentMethodFragmentTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsAddPaymentMethodFragmentTest.kt @@ -35,7 +35,6 @@ internal class PaymentOptionsAddPaymentMethodFragmentTest : PaymentOptionsViewMo ApplicationProvider.getApplicationContext(), ApiKeyFixtures.FAKE_PUBLISHABLE_KEY ) - PaymentSheetFixtures.CONFIG_MINIMUM.parseAppearance() } @After From 7cfed98de9a0b8778d99c699178bcdcb2fecfb23 Mon Sep 17 00:00:00 2001 From: Skyler Reimer Date: Fri, 25 Mar 2022 14:16:31 -0700 Subject: [PATCH 3/5] change from floats to TextUnits for default typography --- .../stripe/android/ui/core/PaymentsTheme.kt | 39 ++++++++++--------- .../BasePaymentMethodsListFragment.kt | 7 +--- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/payments-ui-core/src/main/java/com/stripe/android/ui/core/PaymentsTheme.kt b/payments-ui-core/src/main/java/com/stripe/android/ui/core/PaymentsTheme.kt index ece4fd0feb9..dc0e5d0ec06 100644 --- a/payments-ui-core/src/main/java/com/stripe/android/ui/core/PaymentsTheme.kt +++ b/payments-ui-core/src/main/java/com/stripe/android/ui/core/PaymentsTheme.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -55,12 +56,12 @@ data class PaymentsTypography( val fontWeightMedium: Int, val fontWeightBold: Int, val fontSizeMultiplier: Float, - val xxSmallFont: Float, - val xSmallFont: Float, - val smallFont: Float, - val mediumFont: Float, - val largeFont: Float, - val xLargeFont: Float, + val xxSmallFontSize: TextUnit, + val xSmallFontSize: TextUnit, + val smallFontSize: TextUnit, + val mediumFontSize: TextUnit, + val largeFontSize: TextUnit, + val xLargeFontSize: TextUnit, @FontRes val fontFamily: Int ) @@ -112,12 +113,12 @@ object PaymentsThemeDefaults { fontWeightMedium = FontWeight.Medium.weight, fontWeightBold = FontWeight.Bold.weight, fontSizeMultiplier = 1.0F, - xxSmallFont = 9.0F, - xSmallFont = 12.0F, - smallFont = 13.0F, - mediumFont = 14.0F, - largeFont = 16.0F, - xLargeFont = 20.0F, + xxSmallFontSize = 9.sp, + xSmallFontSize = 12.sp, + smallFontSize = 13.sp, + mediumFontSize = 14.sp, + largeFontSize = 16.sp, + xLargeFontSize = 20.sp, fontFamily = R.font.roboto ) } @@ -184,7 +185,7 @@ fun PaymentsTypography.toComposeTypography(): Typography { // ex: "Select your payment method" in Payment Sheet. val h4 = TextStyle.Default.copy( fontFamily = FontFamily(Font(fontFamily)), - fontSize = (xLargeFont * fontSizeMultiplier).sp, + fontSize = (xLargeFontSize * fontSizeMultiplier), fontWeight = FontWeight(fontWeightBold), ) @@ -192,7 +193,7 @@ fun PaymentsTypography.toComposeTypography(): Typography { // ex: "Pay $50.99" in Payment Sheet's buy button. val h5 = TextStyle.Default.copy( fontFamily = FontFamily(Font(fontFamily)), - fontSize = (largeFont * fontSizeMultiplier).sp, + fontSize = (largeFontSize * fontSizeMultiplier), fontWeight = FontWeight(fontWeightMedium), letterSpacing = (-0.32).sp ) @@ -201,7 +202,7 @@ fun PaymentsTypography.toComposeTypography(): Typography { // ex: Section labels in Payment Sheet val h6 = TextStyle.Default.copy( fontFamily = FontFamily(Font(fontFamily)), - fontSize = (smallFont * fontSizeMultiplier).sp, + fontSize = (smallFontSize * fontSizeMultiplier), fontWeight = FontWeight(fontWeightMedium), letterSpacing = (-0.15).sp ) @@ -210,7 +211,7 @@ fun PaymentsTypography.toComposeTypography(): Typography { // ex: the text used in Payment Sheet's text form elements. val body1 = TextStyle.Default.copy( fontFamily = FontFamily(Font(fontFamily)), - fontSize = (mediumFont * fontSizeMultiplier).sp, + fontSize = (mediumFontSize * fontSizeMultiplier), fontWeight = FontWeight(fontWeightNormal), ) @@ -218,7 +219,7 @@ fun PaymentsTypography.toComposeTypography(): Typography { // ex: the placeholder texts that appear when you type in Payment Sheet's forms. val subtitle1 = TextStyle.Default.copy( fontFamily = FontFamily(Font(fontFamily)), - fontSize = (mediumFont * fontSizeMultiplier).sp, + fontSize = (mediumFontSize * fontSizeMultiplier), fontWeight = FontWeight(fontWeightNormal), letterSpacing = (-0.15).sp ) @@ -227,7 +228,7 @@ fun PaymentsTypography.toComposeTypography(): Typography { // ex: the labels under our payment method selectors in Payment Sheet. val caption = TextStyle.Default.copy( fontFamily = FontFamily(Font(fontFamily)), - fontSize = (xSmallFont * fontSizeMultiplier).sp, + fontSize = (xSmallFontSize * fontSizeMultiplier), fontWeight = FontWeight(fontWeightMedium) ) @@ -235,7 +236,7 @@ fun PaymentsTypography.toComposeTypography(): Typography { // read. Ex: our mandate texts in Payment Sheet. val body2 = TextStyle.Default.copy( fontFamily = FontFamily(Font(fontFamily)), - fontSize = (xxSmallFont * fontSizeMultiplier).sp, + fontSize = (xxSmallFontSize * fontSizeMultiplier), fontWeight = FontWeight(fontWeightNormal), letterSpacing = (-0.15).sp ) diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BasePaymentMethodsListFragment.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BasePaymentMethodsListFragment.kt index 2b2e15e1974..41484c52974 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BasePaymentMethodsListFragment.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BasePaymentMethodsListFragment.kt @@ -108,12 +108,9 @@ internal abstract class BasePaymentMethodsListFragment( 0 ) } - val fontSize = it.convertDpToPx( - ( - PaymentsThemeDefaults.typography.smallFont - * appearance.typography.sizeScaleFactor - ).dp + PaymentsThemeDefaults.typography.smallFontSize.value.dp + * appearance.typography.sizeScaleFactor ) editMenuTextSpan.setSpan( AbsoluteSizeSpan(fontSize.toInt()), From 0fa2fe57f41614847b67b0998964f4c55a1ab387 Mon Sep 17 00:00:00 2001 From: Skyler Reimer Date: Mon, 28 Mar 2022 16:35:34 -0700 Subject: [PATCH 4/5] forgot typography --- .../android/paymentsheet/PaymentSheetConfigurationKtx.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetConfigurationKtx.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetConfigurationKtx.kt index ac02b49613c..c58e59939c3 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetConfigurationKtx.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetConfigurationKtx.kt @@ -62,4 +62,12 @@ internal fun PaymentSheet.Appearance.parseAppearance() { cornerRadius = shapes.cornerRadiusDp, borderStrokeWidth = shapes.borderStrokeWidthDp ) + + PaymentsTheme.typographyMutable = PaymentsThemeDefaults.typography.copy( + fontFamily = typography.fontResId, + fontWeightNormal = typography.normalWeight, + fontWeightMedium = typography.mediumWeight, + fontWeightBold = typography.boldWeight, + fontSizeMultiplier = typography.sizeScaleFactor + ) } From 053b8f49ba306a48ea865605a7e1cd1a08aebc9a Mon Sep 17 00:00:00 2001 From: Skyler Reimer Date: Mon, 4 Apr 2022 17:02:56 -0700 Subject: [PATCH 5/5] api dump --- paymentsheet/api/paymentsheet.api | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/paymentsheet/api/paymentsheet.api b/paymentsheet/api/paymentsheet.api index 412dab6282b..73bd35c66f5 100644 --- a/paymentsheet/api/paymentsheet.api +++ b/paymentsheet/api/paymentsheet.api @@ -168,16 +168,16 @@ public final class com/stripe/android/paymentsheet/PaymentSheet$Colors : android public fun describeContents ()I public fun equals (Ljava/lang/Object;)Z public final fun getAppBarIcon ()I - public final fun getComponentBackground ()I + public final fun getComponent ()I public final fun getComponentBorder ()I public final fun getComponentDivider ()I public final fun getError ()I - public final fun getOnBackground ()I - public final fun getOnPrimary ()I + public final fun getOnComponent ()I + public final fun getOnSurface ()I public final fun getPlaceholderText ()I public final fun getPrimary ()I + public final fun getSubtitle ()I public final fun getSurface ()I - public final fun getTextSecondary ()I public fun hashCode ()I public fun toString ()Ljava/lang/String; public fun writeToParcel (Landroid/os/Parcel;I)V