diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/Inputs.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/Inputs.kt
index 43600137d..28a40953f 100644
--- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/Inputs.kt
+++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/Inputs.kt
@@ -72,6 +72,8 @@ fun Inputs() {
TextAreaInputSample()
Title("Check Box input")
CheckBoxInputSample()
+ DisableCheckBoxInputSample(isChecked = true)
+ DisableCheckBoxInputSample(isChecked = false)
Title("Dropdown")
DropDownSample()
Title("Disable Dropdown")
@@ -385,6 +387,22 @@ fun CheckBoxInputSample() {
)
}
+@Composable
+fun DisableCheckBoxInputSample(
+ isChecked: Boolean,
+) {
+ CheckBoxInput(
+ checked = isChecked,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(top = 8.dp, start = 16.dp, end = 16.dp),
+ text = "This is a disabled checkbox",
+ enabled = false,
+ errorText = null,
+ onCheckedChange = { },
+ )
+}
+
@Composable
private fun DropDownSample(enabled: Boolean = true) {
val items = remember {
diff --git a/catalog/src/main/res/layout/screen_inputs_catalog.xml b/catalog/src/main/res/layout/screen_inputs_catalog.xml
index 43f095f2a..1874c49a9 100644
--- a/catalog/src/main/res/layout/screen_inputs_catalog.xml
+++ b/catalog/src/main/res/layout/screen_inputs_catalog.xml
@@ -311,6 +311,14 @@
app:inputCheckText="This is a disabled CheckBox"
app:inputEnabled="false"/>
+
+
Unit = {},
) {
- Column(modifier = modifier) {
+ Column(
+ modifier = modifier.alpha(enabled)
+ ) {
Row {
CompositionLocalProvider(LocalMinimumTouchTargetEnforcement provides false) {
Checkbox(
checked = checked,
onCheckedChange = onCheckedChange,
enabled = enabled,
+ colors = CheckboxDefaults.colors(
+ checkedColor = MisticaTheme.colors.controlActivated,
+ uncheckedColor = MisticaTheme.colors.control,
+ disabledColor = if (checked) {
+ MisticaTheme.colors.controlActivated
+ } else {
+ MisticaTheme.colors.control
+ }
+ )
)
}
Spacer(modifier = Modifier.width(8.dp))
diff --git a/library/src/main/java/com/telefonica/mistica/input/CheckBoxInput.kt b/library/src/main/java/com/telefonica/mistica/input/CheckBoxInput.kt
index d78e51ff9..12a70ae55 100644
--- a/library/src/main/java/com/telefonica/mistica/input/CheckBoxInput.kt
+++ b/library/src/main/java/com/telefonica/mistica/input/CheckBoxInput.kt
@@ -1,6 +1,7 @@
package com.telefonica.mistica.input
import android.content.Context
+import android.content.res.ColorStateList
import android.graphics.drawable.Drawable
import android.os.Build
import android.text.method.MovementMethod
@@ -12,6 +13,7 @@ import androidx.appcompat.widget.AppCompatCheckBox
import androidx.databinding.*
import com.google.android.material.textfield.TextInputLayout
import com.telefonica.mistica.R
+import com.telefonica.mistica.util.getThemeColor
@BindingMethods(
BindingMethod(
@@ -74,6 +76,7 @@ class CheckBoxInput @JvmOverloads constructor(
setChecked(initialInputChecked)
setText(initialInputText)
configureErrorResetOnCheckChange()
+ setButtonTint()
return findViewById(R.id.text_input_layout)
}
@@ -85,6 +88,18 @@ class CheckBoxInput @JvmOverloads constructor(
}
}
+ private fun setButtonTint() {
+ val states = arrayOf(
+ intArrayOf(android.R.attr.state_checked),
+ intArrayOf(-android.R.attr.state_checked),
+ )
+ val colors = intArrayOf(
+ context.getThemeColor(R.attr.colorControlActive),
+ context.getThemeColor(R.attr.colorControl),
+ )
+ checkBox.buttonTintList = ColorStateList(states, colors)
+ }
+
fun setChecked(checked: Boolean) {
checkBox.isChecked = checked
}
diff --git a/library/src/test/java/com/telefonica/mistica/button/ButtonTest.kt b/library/src/test/java/com/telefonica/mistica/button/ButtonTest.kt
index e02ae44ef..7545424c5 100644
--- a/library/src/test/java/com/telefonica/mistica/button/ButtonTest.kt
+++ b/library/src/test/java/com/telefonica/mistica/button/ButtonTest.kt
@@ -20,6 +20,7 @@ import com.telefonica.mistica.compose.theme.brand.TelefonicaBrand
import com.telefonica.mistica.compose.theme.brand.TuBrand
import com.telefonica.mistica.compose.theme.brand.VivoBrand
import com.telefonica.mistica.testutils.ScreenshotsTest
+import com.telefonica.mistica.testutils.TestUtils
import com.telefonica.mistica.testutils.TestUtils.getAllBrands
import com.telefonica.mistica.testutils.TestUtils.isInverse
import com.telefonica.mistica.util.getThemeColor
@@ -37,7 +38,7 @@ internal class ButtonTest(
) : ScreenshotsTest() {
private val intent = Intent(ApplicationProvider.getApplicationContext(), DummyActivity::class.java).apply {
- this.putExtra(EXTRA_THEME, brand.getBaseThemeForBrand())
+ this.putExtra(EXTRA_THEME, TestUtils.getBaseThemeForBrand(brand))
}
@get:Rule
@@ -105,17 +106,6 @@ internal class ButtonTest(
}
}
-@StyleRes
-private fun Brand.getBaseThemeForBrand(): Int = when (this) {
- MovistarBrand -> R.style.MisticaTheme_Movistar
- VivoBrand -> R.style.MisticaTheme_Vivo
- O2Brand -> R.style.MisticaTheme_O2
- BlauBrand -> R.style.MisticaTheme_Blau
- TuBrand -> R.style.MisticaTheme_Tu
- TelefonicaBrand -> R.style.MisticaTheme_Telefonica
- else -> error("No tests defined for brand $this")
-}
-
@LayoutRes
private fun ButtonStyle.getButtonLayout(): Int = when (this) {
ButtonStyle.PRIMARY -> R.layout.primary_button
diff --git a/library/src/test/java/com/telefonica/mistica/compose/input/CheckBoxInputTest.kt b/library/src/test/java/com/telefonica/mistica/compose/input/CheckBoxInputTest.kt
new file mode 100644
index 000000000..52d261458
--- /dev/null
+++ b/library/src/test/java/com/telefonica/mistica/compose/input/CheckBoxInputTest.kt
@@ -0,0 +1,100 @@
+package com.telefonica.mistica.compose.input
+
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.Surface
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onRoot
+import androidx.compose.ui.unit.dp
+import com.telefonica.mistica.compose.theme.MisticaTheme
+import com.telefonica.mistica.compose.theme.brand.Brand
+import com.telefonica.mistica.testutils.ScreenshotsTest
+import com.telefonica.mistica.testutils.TestUtils
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.ParameterizedRobolectricTestRunner
+import org.robolectric.ParameterizedRobolectricTestRunner.Parameters
+
+@RunWith(ParameterizedRobolectricTestRunner::class)
+class CheckBoxInputTest(
+ private val brand: Brand,
+ private val checked: Boolean,
+ private val isEnabled: Boolean,
+ private val errorText: String?,
+ private val darkTheme: Boolean,
+) : ScreenshotsTest() {
+ @get:Rule
+ val composeTestRule = createComposeRule()
+
+ @Test
+ fun `CheckBoxInput compose screenshot`() {
+ composeTestRule.setContent {
+ MisticaTheme(brand = brand, darkTheme = darkTheme) {
+ Surface(
+ color = MisticaTheme.colors.background
+ ) {
+ CheckBoxInput(
+ modifier = Modifier.padding(16.dp),
+ text = "Some text with terms and conditions",
+ links = listOf(
+ TextLink(link = "terms and conditions", onLinkTapped = {}),
+ ),
+ checked = checked,
+ onCheckedChange = {},
+ errorText = errorText,
+ enabled = isEnabled,
+ )
+ }
+ }
+ }
+
+ val screenshotSuffix = StringBuilder()
+ if (errorText != null) {
+ screenshotSuffix.append("_errorText")
+ }
+ if (!isEnabled) {
+ screenshotSuffix.append("_disabled")
+ }
+
+ if (checked) {
+ screenshotSuffix.append("_checked")
+ } else {
+ screenshotSuffix.append("_unchecked")
+ }
+
+ compareScreenshot(
+ node = composeTestRule.onRoot(),
+ component = "CheckBoxInput",
+ style = null,
+ brand = brand,
+ darkTheme = darkTheme,
+ extra = screenshotSuffix.toString()
+ )
+ }
+
+ companion object {
+ @Suppress("UNUSED")
+ @JvmStatic
+ @Parameters
+ fun brands(): List> {
+ val brands = TestUtils.getAllBrands()
+ val enabled = arrayOf(false, true)
+ val checked = arrayOf(false, true)
+ val errorTexts = arrayOf(null, "Some error text")
+ val darkTheme = arrayOf(false, true)
+
+ return brands.flatMap { brand ->
+ enabled.flatMap { isEnabled ->
+ checked.flatMap { isChecked ->
+ errorTexts.flatMap { errorText ->
+ darkTheme.map { darkTheme ->
+ arrayOf(brand, isEnabled, isChecked, errorText, darkTheme)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/library/src/test/java/com/telefonica/mistica/input/CheckBoxInputTest.kt b/library/src/test/java/com/telefonica/mistica/input/CheckBoxInputTest.kt
new file mode 100644
index 000000000..783780b0b
--- /dev/null
+++ b/library/src/test/java/com/telefonica/mistica/input/CheckBoxInputTest.kt
@@ -0,0 +1,121 @@
+package com.telefonica.mistica.input
+
+import android.content.Intent
+import android.text.Spannable
+import android.text.SpannableString
+import android.text.Spanned
+import android.text.method.LinkMovementMethod
+import android.text.style.ClickableSpan
+import android.view.View
+import android.widget.FrameLayout
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.espresso.Espresso
+import androidx.test.espresso.matcher.ViewMatchers
+import androidx.test.ext.junit.rules.activityScenarioRule
+import com.telefonica.mistica.DummyActivity
+import com.telefonica.mistica.R
+import com.telefonica.mistica.compose.theme.brand.Brand
+import com.telefonica.mistica.testutils.ScreenshotsTest
+import com.telefonica.mistica.testutils.TestUtils
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.ParameterizedRobolectricTestRunner
+import org.robolectric.annotation.Config
+
+@RunWith(ParameterizedRobolectricTestRunner::class)
+class CheckBoxInputTest(
+ private val brand: Brand,
+ private val checked: Boolean,
+ private val isEnabled: Boolean,
+ private val errorText: String?,
+) : ScreenshotsTest() {
+ private val intent = Intent(ApplicationProvider.getApplicationContext(), DummyActivity::class.java).apply {
+ this.putExtra(DummyActivity.EXTRA_THEME, TestUtils.getBaseThemeForBrand(brand))
+ }
+
+ @get:Rule
+ val rule = activityScenarioRule(intent)
+
+ @Test
+ fun `CheckBoxInput XML screenshot light`() {
+ `compare CheckBoxInput XML screenshot`(darkTheme = false)
+ }
+
+ @Config(qualifiers = "+night")
+ @Test
+ fun `CheckBoxInput XML screenshot dark`() {
+ `compare CheckBoxInput XML screenshot`(darkTheme = true)
+ }
+
+ private fun `compare CheckBoxInput XML screenshot`(darkTheme: Boolean) {
+ rule.scenario.onActivity { activity ->
+ val wrapper: FrameLayout = activity.findViewById(R.id.dummy_activity_wrapper)
+ val checkbox = CheckBoxInput(activity).apply {
+ setChecked(checked)
+ error = errorText
+ setText(createSpannableText())
+ setMovementMethod(LinkMovementMethod.getInstance())
+ isEnabled = this@CheckBoxInputTest.isEnabled
+ }
+
+ wrapper.removeAllViews()
+ wrapper.addView(checkbox)
+
+ val screenshotSuffix = StringBuilder()
+ if (errorText != null) {
+ screenshotSuffix.append("_errorText")
+ }
+ if (!isEnabled) {
+ screenshotSuffix.append("_disabled")
+ }
+
+ if (checked) {
+ screenshotSuffix.append("_checked")
+ } else {
+ screenshotSuffix.append("_unchecked")
+ }
+
+ compareScreenshot(
+ node = Espresso.onView(ViewMatchers.withId(R.id.dummy_activity_wrapper)),
+ component = "CheckBoxInputXML",
+ style = null,
+ brand = brand,
+ darkTheme = darkTheme,
+ extra = screenshotSuffix.toString()
+ )
+ }
+ }
+
+ private fun createSpannableText(): Spannable {
+ val termsAndConditions = "terms and conditions"
+ val message = "Some text with $termsAndConditions"
+ return SpannableString(message).apply {
+ setSpan(dummyClickableSpan, message.indexOf(termsAndConditions), message.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+ }
+ }
+
+ companion object {
+ @Suppress("UNUSED")
+ @JvmStatic
+ @ParameterizedRobolectricTestRunner.Parameters
+ fun brands(): List> {
+ val brands = TestUtils.getAllBrands()
+ val enabled = arrayOf(false, true)
+ val checked = arrayOf(false, true)
+ val errorTexts = arrayOf(null, "Some error text")
+
+ return brands.flatMap { brand ->
+ enabled.flatMap { isEnabled ->
+ checked.flatMap { isChecked ->
+ errorTexts.map { errorText ->
+ arrayOf(brand, isEnabled, isChecked, errorText)
+ }
+ }
+ }
+ }
+ }
+
+ private val dummyClickableSpan = object : ClickableSpan() { override fun onClick(widget: View) {} }
+ }
+}
\ No newline at end of file
diff --git a/library/src/test/java/com/telefonica/mistica/testutils/ScreenshotUtils.kt b/library/src/test/java/com/telefonica/mistica/testutils/ScreenshotUtils.kt
index 194906093..97024a7ea 100644
--- a/library/src/test/java/com/telefonica/mistica/testutils/ScreenshotUtils.kt
+++ b/library/src/test/java/com/telefonica/mistica/testutils/ScreenshotUtils.kt
@@ -8,7 +8,11 @@ object ScreenshotUtils {
val componentOrTestName = if(component == null) {
TestUtils.findRunningTestMethodName()
} else {
- "${component}_${style}"
+ var componentName = component
+ if (style != null) {
+ componentName += "_$style"
+ }
+ componentName
}
val brandValue = if (brand != null) {
brand::class.java.simpleName
diff --git a/library/src/test/java/com/telefonica/mistica/testutils/TestUtils.kt b/library/src/test/java/com/telefonica/mistica/testutils/TestUtils.kt
index 2b6617432..08ebf66ea 100644
--- a/library/src/test/java/com/telefonica/mistica/testutils/TestUtils.kt
+++ b/library/src/test/java/com/telefonica/mistica/testutils/TestUtils.kt
@@ -1,7 +1,10 @@
package com.telefonica.mistica.testutils
+import androidx.annotation.StyleRes
+import com.telefonica.mistica.R
import com.telefonica.mistica.compose.button.ButtonStyle
import com.telefonica.mistica.compose.theme.brand.BlauBrand
+import com.telefonica.mistica.compose.theme.brand.Brand
import com.telefonica.mistica.compose.theme.brand.MovistarBrand
import com.telefonica.mistica.compose.theme.brand.O2Brand
import com.telefonica.mistica.compose.theme.brand.TelefonicaBrand
@@ -45,4 +48,15 @@ object TestUtils {
ButtonStyle.LINK_INVERSE -> true
else -> false
}
+
+ @StyleRes
+ fun getBaseThemeForBrand(brand: Brand): Int = when (brand) {
+ MovistarBrand -> R.style.MisticaTheme_Movistar
+ VivoBrand -> R.style.MisticaTheme_Vivo
+ O2Brand -> R.style.MisticaTheme_O2
+ BlauBrand -> R.style.MisticaTheme_Blau
+ TuBrand -> R.style.MisticaTheme_Tu
+ TelefonicaBrand -> R.style.MisticaTheme_Telefonica
+ else -> error("No tests defined for brand $this")
+ }
}
\ No newline at end of file