From 16231f8d418da9481ca5204929a5d2a93be69214 Mon Sep 17 00:00:00 2001 From: Jose Rubio Date: Thu, 12 Sep 2024 15:28:38 +0200 Subject: [PATCH] ANDROID-15168 compose badge improvements (#383) * ANDROID-15168 expose badge text size * ANDROID-15168 trim badgecontent if numeric and > 9 * ANDROID-15168 add more options to the catalog * ANDROID-15168 remove ExperimentalMaterialApi annotation * ANDROID-15168 add screenshots tests * Updated screenshots baseline * ANDROID-15168 add endline * ANDROID-15168 rename tests (and screenshots) * ANDROID-15168 rename tests (and screenshots) --------- Co-authored-by: jeprubio --- .../catalog/ui/compose/components/Badges.kt | 48 ++++++++++- library/screenshots/Badge_non_numeric.png | Bin 0 -> 1880 bytes .../screenshots/Badge_numeric_one_digit.png | Bin 0 -> 2904 bytes .../screenshots/Badge_numeric_two_digits.png | Bin 0 -> 3017 bytes .../telefonica/mistica/compose/badge/Badge.kt | 21 +++-- .../mistica/compose/badge/BadgeTest.kt | 76 ++++++++++++++++++ 6 files changed, 138 insertions(+), 7 deletions(-) create mode 100644 library/screenshots/Badge_non_numeric.png create mode 100644 library/screenshots/Badge_numeric_one_digit.png create mode 100644 library/screenshots/Badge_numeric_two_digits.png create mode 100644 library/src/test/java/com/telefonica/mistica/compose/badge/BadgeTest.kt diff --git a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/Badges.kt b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/Badges.kt index 52fef64ee..5be3cff05 100644 --- a/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/Badges.kt +++ b/catalog/src/main/java/com/telefonica/mistica/catalog/ui/compose/components/Badges.kt @@ -7,12 +7,21 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material.BadgedBox import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.Icon import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp +import com.telefonica.mistica.catalog.R import com.telefonica.mistica.compose.badge.Badge +import com.telefonica.mistica.compose.button.Button @OptIn(ExperimentalMaterialApi::class) @Composable @@ -24,9 +33,44 @@ fun Badges() { verticalArrangement = Arrangement.spacedBy(16.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { + var badgeContent: String? by rememberSaveable { mutableStateOf(null) } + var show: Boolean by rememberSaveable { mutableStateOf(false) } Spacer(modifier = Modifier.height(16.dp)) - Badge() - Badge(content = "1") + BadgedBox( + badge = { + if (show) { + Badge(content = badgeContent) + } + } + ) { + Icon( + painter = painterResource(id = R.drawable.icn_creditcard), + contentDescription = null, + ) + } + Button( + text = "Toggle", + onClickListener = { + badgeContent = "" + show = !show + } + ) + + Button( + text = "Show with one digit number", + onClickListener = { + show = true + badgeContent = (0..9).random().toString() + } + ) + + Button( + text = "Show with two digit number", + onClickListener = { + show = true + badgeContent = (10..99).random().toString() + } + ) } } diff --git a/library/screenshots/Badge_non_numeric.png b/library/screenshots/Badge_non_numeric.png new file mode 100644 index 0000000000000000000000000000000000000000..238a47932af01f8f464ec022cdb4c770b3e1896c GIT binary patch literal 1880 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 literal 0 HcmV?d00001 diff --git a/library/screenshots/Badge_numeric_two_digits.png b/library/screenshots/Badge_numeric_two_digits.png new file mode 100644 index 0000000000000000000000000000000000000000..2e3e66199d17cdbb726529ab155bddab631d827b GIT binary patch literal 3017 zcmd5;`8(U`7S}tLG*wG&Q7Wj4R%`31pk!+43_8(~E~W%i)O2hS4b_N@xMecd7ELXo zb;ra~RIQ<;87;B2T8dF2iG+*^QCmnwaxv|5=Rdgf!}t9@=RN0h-t+mq?{l6*JP-eJ zKky(>PEKyW$5(DX+kfWH2To;Li zbQxf3w0AEfJ?IR4ef)-9J3oTaV7cCFy54@Wlxl%(7?0&Ac3{_qQBn4IY1wB%Tx}Ux z&Ml2C=PIuRGKM}=qwh%ts93q7el#L{rmU_X^wa;tbsyw;qqQW`l8S)cdWCUr>uY)$ zIDJJ}C@7>s8%)q(bRfDE&02Qk#fxb)A2ogBlN(YPa=knCf?AT!e48}p3QXA>Stxh*azvu_7Qq+DzckXfC1MC^-= z2LrmlOJ<*MjOAOjA_gOXkX4hI58|3i>kaPD2j~yKcgk!}@i;xcDtxDrVeToPR;H|P zFDwjW>YZbIK!UC{Ppm=+A{kLtGYWJH~ zobA6{HCaw0Gxolu`GXI_7nUTYO>xV;VJR^r4f>fGCi`(XbyGl>9|0v{@NoZ9%nj;F z-61q78=u2`fh!TOS1%wdogT_o?j0Dhy;GtLfmUd4UM1?+O}2jc*0d@;jrEe+u}B%@ zyN$_KPS9}~GxN=4A+sdq=wy?(e2Y#v`;SffM*nU0gQ1R?SSxE=Mf~u6qQ`H!a$6XS zPK-&zt9-njQcL!c&6_BcK*SbZ?e*PSBJHD}DgQk-T8CxtaB!GbNSJV6e79DBVK#+Z zEM1(WsFVRM`eM=YO8L#VRh2Xl++kH%pPLcZMi%!*{PIg10izr%RwZDTiN{(+FZv0) z36I1KrqG|iZB3j87nt#ATNCaRO!oo|Z>Zq|gzg}A)AARLX)ACobqFb*D+?prp*fci z50eC8X$T5Hf^nF&?0s~YG=b58 z(aMsB06lu0CiAP*@lOvy-rxK@~g8i_8*Yi6sH1;BZzaOo99O3zS)U@_H6!N?Yrk5SZKAVmeeu*HfkE zf6watthO^LrMlXWqkY`>j~{-}hEqe4lfjkNLKfZ%gm2~y<7%;6>G{+aFXvx{r5!o9 zGNjyQH{p;67C7+)-<)zz@fox8uA%|WyH@4Sa3`cHv%ioC6C&VD$ zO62l=Nsqlcp!SQNEHWx~mPsm19H#K$-B2Wro8_20F+J=3k{4_-S#;2ULUQCgfcj1g zt~VOWey5qj1{&69&X1gha4ML+x@i-kevDH~EeK~k)YSwRQm z9OJ5F-Z0(X-$OENZTAtD`hA)+WhWWg>^$CFF8&$(Yd=6wbS<1g9h9f!EI!p3i>=f6=nF1rH`&b>uiRr3 z?}2jIi2!8@sAGHKX>84?&NQzTnNvW^ZahlaPI{Mp0|4jDVxjk*>;l=KD2ZUVhT=3m znFD=Jt@vL(D6Zu$eECpU$5J=Pccn#X$Klc$48@aMmp)leI}|davekF-;w+8?Gu_QH z*tO<4E+46~K^DBfXx&ca|2;&%>$YT@)ON|wto<1uaev!1uy}6m9|M3t%n62yv$hgh z=!*mBxuG<3k@?8hU%&^GUA^Fq_haUmqj=MPnN$8VeDUt_?}A%XQ)}#V-(M>QoAcUa z*kj4Eo4cGE`5a#MfmCnUFp!ocsJW=M8CEap@!Bav?Q9-iRR{91?$-ugFNicJz>bcM zJ*b%J|J_X%=jZK9Yicq_U(F3gAiN$26mLwV>?nH%er*#A6?ZM~ya@<*YoY$u8iIZc zpkC|}%&mRr!rPyq2(N9*!*hK Q_J}U$;SP7JbqON;7ovZwT>t<8 literal 0 HcmV?d00001 diff --git a/library/src/main/java/com/telefonica/mistica/compose/badge/Badge.kt b/library/src/main/java/com/telefonica/mistica/compose/badge/Badge.kt index a1bafb607..074853b42 100644 --- a/library/src/main/java/com/telefonica/mistica/compose/badge/Badge.kt +++ b/library/src/main/java/com/telefonica/mistica/compose/badge/Badge.kt @@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.runtime.Composable @@ -14,14 +13,16 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import com.telefonica.mistica.compose.theme.MisticaTheme import com.telefonica.mistica.compose.theme.brand.MovistarBrand +import androidx.compose.material.Badge as MaterialBadge -@ExperimentalMaterialApi @Composable fun Badge( modifier: Modifier = Modifier, + textSize: TextUnit = TextUnit.Unspecified, content: String? = null, ) { if (content.isNullOrEmpty()) { @@ -33,26 +34,36 @@ fun Badge( .size(8.dp), ) { } } else { - androidx.compose.material.Badge( + MaterialBadge( backgroundColor = MisticaTheme.colors.badge, modifier = modifier.testTag(BadgeTestTags.BADGE_NUMBER), ) { Text( modifier = Modifier.testTag(BadgeTestTags.BADGE_NUMBER_VALUE), - text = content, + text = getBadgeContent(content), + fontSize = textSize, color = MisticaTheme.colors.textPrimaryInverse, ) } } } +private fun getBadgeContent(content: String) = if (content.all { it.isDigit() }) { + if (content.toLong() > 9) { + "9+" + } else { + content + } +} else { + content +} + object BadgeTestTags { const val BADGE = "badge" const val BADGE_NUMBER = "badge_number" const val BADGE_NUMBER_VALUE = "badge_number_value" } -@ExperimentalMaterialApi @Preview(showBackground = true) @Composable fun BadgePreview() { diff --git a/library/src/test/java/com/telefonica/mistica/compose/badge/BadgeTest.kt b/library/src/test/java/com/telefonica/mistica/compose/badge/BadgeTest.kt new file mode 100644 index 000000000..ed84befe7 --- /dev/null +++ b/library/src/test/java/com/telefonica/mistica/compose/badge/BadgeTest.kt @@ -0,0 +1,76 @@ +package com.telefonica.mistica.compose.badge + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.padding +import androidx.compose.material.BadgedBox +import androidx.compose.material.Icon +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onRoot +import androidx.compose.ui.unit.dp +import com.telefonica.mistica.R +import com.telefonica.mistica.compose.theme.MisticaTheme +import com.telefonica.mistica.compose.theme.brand.MovistarBrand +import com.telefonica.mistica.testutils.ScreenshotsTest +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class BadgeTest: ScreenshotsTest() { + @get:Rule + val composeTestRule = createComposeRule() + + @Test + fun `Badge non numeric`() { + `when some badge`("") + + `then screenshot is OK`() + } + + @Test + fun `Badge numeric one digit`() { + `when some badge`(ONE_DIGIT_CONTENT) + + `then screenshot is OK`() + } + + @Test + fun `Badge numeric two digits`() { + `when some badge`(TWO_DIGITS_CONTENT) + + `then screenshot is OK`() + } + + private fun `when some badge`(value: String) { + composeTestRule.setContent { + MisticaTheme(brand = MovistarBrand) { + Box(modifier = Modifier.padding(24.dp)) { + BadgedBox( + badge = { + Badge( + content = value + ) + } + ) { + Icon( + painter = painterResource(id = R.drawable.icn_creditcard), + contentDescription = "credit card" + ) + } + } + } + } + } + + private fun `then screenshot is OK`() { + compareScreenshot(composeTestRule.onRoot()) + } + + companion object { + private const val ONE_DIGIT_CONTENT = "9" + private const val TWO_DIGITS_CONTENT = "99" + } +}